题目:智力大冲浪
题意:
刚开始没看懂……
摘自~Lanly~
①. 4 70
②. 2 60
③. 4 50
④. 3 40
⑤. 1 30
⑥. 4 20
⑦. 6 10
其中第一列为编号,第二列为规定期限ti,第三列为未完成的赔钱。
显然,对于第一个时段,我们最优解是完成第五个游戏,这样赔钱数为0,已完成游戏⑤。
对于第二个时间段,我们最优解是完成第二个游戏,这样赔钱数还是为0,已完成游戏⑤②。
对于第三个时间段同理已完成⑤②④。
对于第四个时间段,游戏①我们肯定是要选的,因为它赔钱数最多,剩下的③⑥加起来会赔70元,但在这里,我们注意到,我们已完成的游戏里面⑤的赔钱数是30,但③的赔钱数是50,如果我们完成③放弃⑤,赔钱数只是50比之前优,而这个③我们就可以放在第一个时间段去完成
剩下的⑥所赔的钱都比已完成的少,就也放弃了。
第五个时间段,我们就只能完成⑦了。
思路:
贪心。
根据扣得钱从大到小排序,在选择时优先考虑靠前的。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 500
struct gme{
int t,x;
bool operator < (const gme& oth) const {
return x>oth.x||(x==oth.x&&t<oth.t);
}
};
int mny,n;
gme a[maxn+5]={0};
bool f[maxn+5]={0};
void readin(){
scanf("%d%d",&mny,&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].t);
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i].x);
}
sort(a+1,a+n+1);
}
int slv(){
int ans=mny;
for(int i=1;i<=n;i++){
for(int j=a[i].t;j>=1;j--){
if(!f[j]) {
f[j]=1;
goto End;
}
}
ans-=a[i].x;
End:;
}
return ans;
}
int main(){
readin();
sort(a+1,a+n+1);
int ans=slv();
printf("%d",ans);
return 0;
}