bool f[100010];
int use[100010];
int main()
{
int cash,n,i,j,c[15],v[15];
freopen("1276.txt","r",stdin);
while(scanf("%d%d",&cash,&n)!=EOF)
{
for(i=1;i<=n;i++){
scanf("%d%d",c+i,v+i);
if(v[i]>cash) c[i]=0;
}
if(cash==0||n==0) { puts("0"); continue; }
memset(f,0,sizeof(f));
f[0]=1;
for(i=1;i<=n;i++){
if(c[i]==0) continue;
memset(use,0,sizeof(use));
for(j=v[i];j<=cash;j++){
if(!f[j]&&f[j-v[i]]&&use[j-v[i]]<c[i]){
f[j]=1;
use[j]=use[j-v[i]]+1;
}
}
}
for(i=cash;;i--)
if(f[i]){
printf("%d\n",i); break;
}
}
}
PKU1014
[问题描述]
给出6堆大理石每堆的石子数目,每堆分别对应各自重量。6堆重量分别为1,2,3,4,5,6
问是否能把这些大理石分为重量相同的两堆
[问题上限]
大理石最多总共20000块
明显的多重背包问题,首先确定所有石子的总重量,如果为奇数当然是不可能平分的,否则设背包容量为sum/2,是否刚好能取一些石子使得重量刚好装满背包。
bool f[120010];
int use[120010];
int main()
{
int i,j,sum,c[10],TT=0;
while(1){
sum=0;
for(i=1;i<=6;i++){
scanf("%d",c+i);
sum+= i*c[i];
}
if(sum==0) break;
printf("Collection#%d:\n",++TT);
if(sum&1) { puts("Can'tbe divided.\n"); continue; }
sum/=2;
memset(f,0,sizeof(f));
f[0]=1;
for(i=1;i<=6;i++){
if(c[i]==0) continue;
memset(use,0,sizeof(use));
for(j=i;j<=sum;j++){
if(!f[j]&&f[j-i]&&use[j-i]<c[i]){
f[j]=1;
use[j]= use[j-i]+1;
}
}
}
if(f[sum]) puts("Canbe divided.\n");
else puts("Can'tbe divided.\n");
}
}
PKU1276
有N种面值的钞票,其中面值为Di的钞票有ni种,
如N=3, n1=10, D1=100, n2=4, D2=50, n3=5, D3=10; 问用这些钞票能组合出来的
面值中不超过某给定数cash的最大值是多少?
可以使用上一题的模板: