题目:http://acm.hdu.edu.cn/showproblem.php?pid=5501
分析:首先贪心分析。考虑…x1 x2….互换x1x2不影响其他题对答案的贡献,那么得出互换的条件,于是得到结论:按B/C的顺序排序。这里注意,不要写除法,会被卡,分子分母交叉乘起来比较大小。
然后需要一个01背包DP。这题与SD夏令营挂项链一题极为相似,当时我也没有想明白为什么贪心后还要DP,现在终于明白:贪心只是确定了选择的最优顺序,但是并没有决定选哪些,如果贪心依据不包含除法,就不用DP一遍了。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int Tmax=1005,Tmax2=3005;
struct node{
long long int A,B,C;
bool operator <(const node &rhs)const
{
return B*rhs.C>rhs.B*C;
}
};
node data[Tmax];
int n,t;
long long f[Tmax2],ans;
void work()
{
int i,j;
for(i=1;i<=n;i++)
for(j=t;j>=data[i].C;j--)
f[j]=max(f[j],f[j-data[i].C]+max((long long )0,data[i].A-data[i].B*j));
for(i=0;i<=t;i++)
ans=max(ans,f[i]);
return;
}
int main()
{
int T,i;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&t);
ans=0;
memset(f,0,sizeof(f));
for(i=1;i<=n;i++)
scanf("%I64d%I64d%I64d",&data[i].A,&data[i].B,&data[i].C);
sort(data+1,data+1+n);
work();
printf("%I64d\n",ans);
}
return 0;
}