砝码称重V2

砝码称重V2
总时间限制: 1000ms         内存限制: 65536kB
描述

设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=100,000),要求:计算用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况。

输入
一行,包括六个正整数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背包 
//转化成01背包问题。
//例:
//22=1+2+4+8+7(存于w[i]数组中) 
//其中1,2,4,8能组成1~15中的任意值,再加7能组成1~22的任意值。
//f[j]=f[j]||f[j]-w[i];
//f[j]表示能否称出j;
#include<cstdio>
int a[100002]={0},n;
bool ans[100002];
int a1,a2,a3,a5,a10,a20;
void work(int x,int k){
    int m=1;
    while(x>m){
        a[0]++;
        a[a[0]]=m*k;
        x-=m;
        m=m<<1;
    }
    if(x>0) a[0]++,a[a[0]]=x*k;
}
int main(){
    scanf("%d%d%d%d%d%d",&a1,&a2,&a3,&a5,&a10,&a20);
    a[0]=0;
    work(a1,1);
    work(a2,2);work(a3,3);
    work(a5,5);work(a10,10);work(a20,20);
    ans[0]=1;
    for(int i=1;i<=a[0];i++)
        for(int j=100000;j>=a[i];j--){
            ans[j]=ans[j]||ans[j-a[i]];
        }
    n=0;
    for(int i=1;i<=100000;i++) if(ans[i]) n++;
    printf("Total=%d
",n);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/qingang/p/5371592.html