NOIP 2006 提高组 复赛 budget 金明的预算方案
1.题目中透着01背包问题,样例也模拟出来了:400*3+500*2=2200
2.如何选择主次,存在疑虑。
//p1064 金明的预算方案
//读完题目,有条件限制的01背包问题
//编编看,看是否能理清关系
//第一步,排序,按主件在前,附件在后的办法进行处理。
//写完代码,测试样例都无法通过,明白该题得寻求外界帮助。
//《新编全国青少年信息需竞赛培训教材(复赛篇)》虽是pascal,但里面关于该题的叙述还是很有参考价值
//重写代码。 采用一维数组
//该题编写经历了三天,01背包问题,有了长足的进步。
#include <stdio.h>
#include <string.h>
int f[3200+100];//此处写成 f[60+10]
int v[60+10][3],p[60+10][3];//0主件1附件1 2附件2
int fun(int a,int b){
if(a>b)
return a;
else
return b;
}
int main(){
int N,m,i,j,a,b,c,n,v0,v1,v2,p0,p1,p2;
memset(v,0,sizeof(v));
scanf("%d%d",&N,&m);
n=N/10;
for(i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
if(c==0)
c=i;
for(j=0;j<=2;j++)
if(v[c][j]==0){//1此处写成 v[i][j]==0
v[c][j]=a/10;//缩小10倍
p[c][j]=v[c][j]*b;
break;//4漏了break,调了好长时间。是跟踪了代码,才发现此处有问题。
}
}
for(i=0;i<=n;i++)
f[i]=0;
for(i=1;i<=m;i++)
for(j=n;j>=0;j--)
if(v[i][0]>0){//2漏了此条件
v0=v[i][0];
v1=v[i][1];
v2=v[i][2];
p0=p[i][0];
p1=p[i][1];
p2=p[i][2];
if(j>=v0)
f[j]=fun(f[j],f[j-v0]+p0);
if(j>=v0+v1)
f[j]=fun(f[j],f[j-v0-v1]+p0+p1);
if(j>=v0+v2)//3漏了此种情况
f[j]=fun(f[j],f[j-v0-v2]+p0+p2);
if(j>=v0+v1+v2)
f[j]=fun(f[j],f[j-v0-v1-v2]+p0+p1+p2);
}
printf("%d\n",f[n]*10);
}
2017-4-19 22:20