题目链接:Weekly Training Farm 22 - B - ACM-ICPC Contest
可以看成背包问题,每道题看成一个物品。
对于相同的问题组,当按完成时间升序做题时,罚时最小。所以先对所有问题排一下序。
然后就是普通的0-1背包。
不过要重定义一下max函数,当做题数最多,罚时最小时,是所要求的最值。然后dp就行了。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+7; #define mp make_pair #define fi first #define se second typedef pair<ll,ll> pr; int n; pr p[maxn]; pr dp[307]; pr max_pair(pr a, pr b) { if(a.first!=b.first) { if(a.first>b.first) return a; else return b; } else { if(a.second<b.second) return a; else return b; } } int main() { ios::sync_with_stdio(false); while(cin>>n) { for(int i=0;i<n;i++) cin>>p[i].fi>>p[i].se; sort(p,p+n); for(int j=0;j<=300;j++) dp[j]=mp(-1,-1); dp[0]=mp(0,0); pr ans=mp(0,0); for(int i=0;i<n;i++) for(int j=300;j>=p[i].fi;j--) { if(dp[j-p[i].fi].first!=-1) dp[j]=max_pair(mp(dp[j-p[i].fi].first+1,dp[j-p[i].fi].second+j+p[i].se*20),dp[j]); } for(int i=0;i<=300;i++) ans=max_pair(ans,dp[i]); cout<< ans.first << " " <<ans.second<<endl; } return 0; }