题目链接:http://exam.upc.edu.cn/problem.php?id=3401
这个题综合了 排序和01背包 ,和ZOJ一题很像。
可能就是从ZOJ那里,这个题有一个问题,就是排序,01背包大家都懂。
排序成了这个题最核心的问题了。
原来我的想法是(x.a-(x.d*x.c))<(y.a-(y.d*y.c));
后来发现我的想法十分幼稚,因为这个只是单纯把一道题的价值最大化了,
但是这个题需要的排序,需要的全局最优,至于怎么实现,我是看了别人的博客才知道原来是怎么一回事。
就是把两个题目的先后顺序的最大化,
比如 先做第一题 (x.c)*x.d+(x.c+y.c)*y.d;
做第二题: (y.c)*y.d+(y.c+x.c)*x.d;
(x.c)*x.d+(x.c+y.c)*y.d < (y.c)*y.d+(y.c+x.c)*x.d 进行排序;
01背包注意,一定是过程中出现最大值,不一定是T的时候出现最大值。
贴上代码:
#include<bits/stdc++.h>
using namespace std;
int T,n,dp[1000400]={0};
typedef struct point{
int a,c,d;
}point;
point p[2020];
int cmp(point x,point y){
return x.c*x.d+(y.c+x.c)*y.d < y.c*y.d+(y.c+x.c)*x.d ;
}
int main()
{
scanf("%d%d",&n,&T);
for(int i=0;i<n;i++){
scanf("%d",&p[i].a);
}for(int i=0;i<n;i++){
scanf("%d",&p[i].d);
}for(int i=0;i<n;i++){
scanf("%d",&p[i].c);
}
sort(p,p+n,cmp);
memset(dp,0,sizeof(dp));
int maxz=-1;
for(int i=0;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].d*(j)));
maxz=max(maxz,dp[j]);
}
}
/*for(int i=0;i<=T;i++){
printf("%d%c",dp[i],i==T?'\n':' ');
}*/
printf("%d\n",maxz);
return 0;
}