这题的01背包的特点很容易看出来,但其实发现,这个题讲究加入时候的顺序。
于是,用贪心排序,如代码中所示,如果A在B前面造成的分数损失更小,则排在前面。。。其实这个我也是猜的。。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int dp[1005][3005]; struct Problem{ int a,b,c; }pro[1005]; bool cmp(Problem a,Problem b){ if(a.c*b.b<b.c*a.b) return true; else if(a.b*a.c+(a.c+b.c)*b.b==b.b*b.c+(a.c+b.c)*a.b){ if(a.b>b.b) return true; } return false; } int main(){ int T,n,t; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&t); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ scanf("%d%d%d",&pro[i].a,&pro[i].b,&pro[i].c); } sort(pro+1,pro+1+n,cmp); for(int j=1;j<=n;j++){ for(int i=1;i<=t;i++){ dp[j][i]=max(dp[j][i],dp[j-1][i]); if(i<pro[j].c) continue; dp[j][i]=max(dp[j][i],dp[j-1][i-pro[j].c]+pro[j].a-pro[j].b*i); } } int ans=dp[n][0]; for(int i=1;i<=t;i++){ ans=max(ans,dp[n][i]); } printf("%d ",ans); } return 0; }