【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;
}

浙公网安备 33010602011771号