砝码称重
问题描述:
设有1g,2g,3g,5g,10g,20g的砝码各若干枚(其总重≤1000g),要求:
输入:
a1 a2 a3 a4 a5 a6(表示1g砝码有a1个,2g砝码有a2个,......20g砝码有a6个)
输出:
Total=N (N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)
输入样例:
1 1 0 0 0 0
输出样例:
Total=3,表示可以称出1g,2g,3g三种不同的重量
把题目转换成01背包,把每次进来的物品个数一个个的拆分为单个物品存放在c数组内
设f[i][j]为体积为i的方案总和
那么,当第i件物品不选时,f[i][j]=f[i-1][j].
那么如果选择了呢,f[i][j]=f[i-c[i]];
那么两者累加,就是f[i][j]=f[i-1][j]+f[i-c[i]].
为了减少空间浪费,去掉第一维,可以得到:
f[i]=f[i]+f[i-c[i]],也就是f[i]+=f[i-c[i]].
最后附上代码:
#include<cstdio>//没看题解! #include<iostream> using namespace std; int f[1005],v[1005],n=1,tmp; const int num[10]={0,1,2,3,5,10,20}; int main(){ for(int i=1;i<=6;i++){ scanf("%d",&tmp); for(int j=1;j<=tmp;j++)v[n++]=num[i]; }f[0]=1; int sum=0,ans=0; for(int i=1;i<=n;i++)sum+=v[i];//转容量 for(int i=1;i<=n;i++) for(int j=sum;j>=v[i];j--) f[j]=f[j-v[i]]; for(int i=1;i<=sum;i++)if(f[i])ans++; printf("Total=%d",ans); //system("pause"); return 0; }