题目链接:https://loj.ac/problem/10004
题目描述
小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则:
首先,比赛时间分为n个时段,它又给出了很多小游戏,每个小游戏都必须在规定期限前完成。如果一个游戏没能在规定期限 t 前完成,则要从奖励费m 元中扣去一部分钱w,w为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱!
输入格式
输入共四行。
第一行为m,表示一开始奖励给每位参赛者的钱;
第二行为n,表示有n个小游戏;
第三行有n个数,分别表示游戏1到n的规定完成期限;
第四行有n个数,分别表示游戏1到n不能在规定期限前完成的扣款数。
输出格式
输出仅一行,表示小伟能赢取最多的钱。
样例
样例输入
1000074 2 4 3 1 4 670 60 50 40 30 20 10
样例输出
9950
数据范围与提示
对于100%所有数据,有n ≤ 500,1 ≤ t ≤ n
分析
扣款数多的肯定要先完成,但如何避免把扣款数高的题目过早完成而导致本来能完成的题目完不成了呢?
因为扣款数多的要优先完成,所以我们根据扣款数对任务从大到小进行排序,然后从第一个(扣款数最多的)任务开始,将他放到他能放到的最后期限去做,(目的是保证不出现前面所说的问题),排在后面可以为时间要求更高的任务留出时间。
代码如下:
#include <iostream>#include <algorithm>using namespace std;typedef struct{int num;// num 表示完成期限 int count; // count 表示扣款数 }goods;int cmp(goods x,goods y){return x.count > y.count;}int main(){int all,n,i,book[501]={0},t;goods a[501];cin >> all;cin >> n;for(i=1;i<=n;i++)cin >> a[i].num;for(i=1;i<=n;i++)cin >> a[i].count;sort(a+1,a+n+1,cmp);// 核心代码段 // **********for(i=1;i<=n;i++){for(t=a[i].num;t>0;t--){if(book[t] == 0){book[t] = 1;break;}}if(t == 0)all -= a[i].count;}// ************cout << all << endl;}
并查集算法:时间上更优
#include <iostream>#include <algorithm>#include <bits\stdc++.h>const int maxn = 501;using namespace std;typedef struct{int d;int c;}goods;bool cmp(goods x,goods y){return x.c > y.c;}int fa[maxn];int getfa(int x){if(fa[x] == x)return x;elsereturn fa[x] = getfa(fa[x]);}int main(){int all,i,n,maxx=0;goods a[maxn];cin >> all;cin >> n;for(i=1;i<=n;i++)cin >> a[i].d;for(i=1;i<=n;i++){cin >> a[i].c;maxx = max(a[i].c,maxx); }sort(a+1,a+1+n,cmp);for(i=1;i<=maxx;i++)fa[i]=i;for(i=1;i<=n;i++){int j = getfa(a[i].d);if(j){fa[j] = j-1;}if(!j)all -= a[i].c;}cout << all;}
如果觉得《智力大冲浪 【贪心】》对你有帮助,请点赞、收藏,并留下你的观点哦!