【9905】砝码称重

Time Limit: 10 second
Memory Limit: 2 MB

问题描述
设有1g,2g,3g,5g,10g,20g的砝码各若干枚(其总重≦1000g),要求:

Input

a1 a2 a3 a4 a5 a6(表示1g砝码有a1个,2g砝码有a2个,......20g砝码有a6个

Output

Total=n(n表示用这些砝码能称出不同重量的个数,但不包括一个砝码也不用的情况,注意第一个T是大写的)


Sample Input

1 1 0 0 0 0

Sample Output

Total=3

Sample Input1

0 3 2 7 4 5


Sample Output1

Total=185

【题解】

可以看成6个物品,6个物品的多重背包问题。

然后按照多重背包的更新顺序,来确定某一个值是否能达到。

一开始can[0] = true;

然后if (can[j-w[i]*k)

can[j] = true;

因为只要再拿k个i砝码就能够组合成J了。

w[]数组的1..6的值是固定的就是1,2,3,5,10,20

只要注意更新的顺序就可以了,不会很难。

最后从1-1000扫描一遍if (can[i]) tot++;

【代码】

#include <cstdio>
#include <cstring>

const int w[7] = {0,1,2,3,5,10,20};

int num[7],tot = 0;
bool can[1010];

void input_data()
{
	for (int i = 1; i <= 6;i++)
		scanf("%d",&num[i]);
}

void get_ans()
{
	memset(can,false,sizeof(can));
	can[0] = true;
	for (int i = 1;i <= 6;i++) //枚举6个物品 
		for (int j = 1010;j >= 0;j--) //枚举最大容量 (就是数字的最大值,题目有说不大于1000) 
			for (int k = 1;k <= num[i];k++)// 枚举该物品的使用数量 
				{
					if (j - w[i]*k < 0)
						continue;
					if (can[j-w[i]*k]) //如果j-w[i]*k这个重量可以达到。那么j这个重量也可以达到! 
						can[j] = true;
				}	
	for (int i = 1;i <= 1000;i++)
		if (can[i])
			tot++;
}

void output_ans()
{
	printf("Total=%d",tot);		
}

int main()
{
	//freopen("F:\\rush.txt","r",stdin);
	input_data();
	get_ans();
	output_ans();
	return 0;	
}



posted @ 2017-10-06 19:23  AWCXV  阅读(182)  评论(0编辑  收藏  举报