砝码称重

问题描述:

  设有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;		    
    
}

  

原文地址:https://www.cnblogs.com/wangshengjun/p/10223973.html