这道题是一道非常经典的题。现在有A1,B1,C1和A2,B2,C2这两道题,如果先做1再做2的得分是A1-B1*C1+A2-B2*(C1+C2),如果先做2在做1的得分是A2-B2*C2+A1-B1*(C1+C2),令先做1再做2的得分更高些,那么有A1-B1*C1+A2-B2*(C1+C2) >= A2-B2*C2+A1-B1*(C1+C2),解得B1*C2>=B2*C1
所以,只要B1*C2>=B2*C1,那么先做题1再做题2的分数就会更高。
所以,我们只需要根据这个来排序,再做dp,就能得到答案了.
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1100;
const int maxt=3300;
struct node
{
int a,b,c;
bool operator<(node &F)const
{
return b*F.c>F.b*c;
}
}p[maxn];
int dp[maxt];
int main()
{
int T,n,t;
cin>>T;
while(T--)
{
cin>>n>>t;
for(int i=1;i<=n;i++)
{
cin>>p[i].a>>p[i].b>>p[i].c;
}
sort(p+1,p+n+1);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
for(int j=t;j>=p[i].c;j--)
{
dp[j]=max(dp[j],dp[j-p[i].c]+p[i].a-p[i].b*j);
}
}
int ans=0;
for(int i=0;i<=t;i++)
ans=max(ans,dp[i]);
cout<<ans<<endl;
}
}