智力大冲浪
题目描述
小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者 m m m 元。先不要太高兴,因为这些钱还不一定都是你的。接下来主持人宣布了比赛规则:
首先,比赛时间分为 n n n 个时段,它又给出了很多小游戏,每个小游戏都必须在规定期限 t i t_i ti 前完成。如果一个游戏没能在规定期限前完成,则要从奖励费 m m m 元中扣去一部分钱 w i w_i wi, w i w_i wi 为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱!
输入格式
第一行为 m m m,表示一开始奖励给每位参赛者的钱;
第二行为 n n n,表示有 n n n 个小游戏;
第三行有 n n n 个数,分别表示游戏 1 1 1 到 n n n 的规定完成期限;
第四行有 n n n 个数,分别表示游戏 1 1 1 到 n n n 不能在规定期限前完成的扣款数。
输出格式
输出仅一行,表示小伟能赢取最多的钱。
样例 #1
样例输入 #1
10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10
样例输出 #1
9950
提示
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 500 1 \le n \le 500 1≤n≤500, 1 ≤ m ≤ 5 × 1 0 5 1 \le m \le 5 \times 10^5 1≤m≤5×105, 1 ≤ t i ≤ n 1 \le t_i \le n 1≤ti≤n, 1 ≤ w i ≤ 1000 1 \le w_i \le 1000 1≤wi≤1000。
思路:
贪心过程 先把钱数从大到小排序,因为尽可能要拿更多的奖品,所以我们把一个每一个价值高的任务尽可能的放在截止时刻去完成,为什么呢因为如果第一大的是4,第二大的是1,第三大是2,防止四占走了1的位置,所以就把能放截止的放截止,不能放在最后的就往前搜搜看,如果某一刻没有任务,就放在那一刻去完成,我们可以借助bool数组进行标记,某一个任务完成了可以改成0,把接了的任务改成0,没接到的任务减去即可
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n, sum,mmax,k,num;
struct Node {//方便处理数据
int w, t;
}lst[550];
bool st[550];
bool cmp(Node x, Node y){
return x.w>y.w;//排序
}
int main()
{
cin >> sum;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> lst[i].t;
}
for (int i = 1; i <= n; i++)
cin >> lst[i].w;
sort(lst+1, lst + n+1, cmp);//排序
for (int i = 1; i <=n; i++)
{
if (!st[lst[i].t]) {
st[lst[i].t] = true;//标记
lst[i].w = 0;//归零
}
else
{
for (int j = lst[i].t - 1; j >= 1; j--)//往前找
if (!st[j]) {//没任务
st[j] = true;//接任务
lst[i].w = 0;//归零
break;//结束往前找的过程
}
}
}
for (int i = 1; i <= n; i++){
sum -= lst[i].w;//减去无法完成的
}
cout << sum;
return 0;
}