砝码称重---背包动规

题目描述:

设有1g,2g,3g,5g,10g,20g的砝码各若干枚(其总重≤50000g)。

输入格式:

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

输出格式:

Total=N(N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)

样例输入:

1  1  0   0   0   0

样例输出:

Total=3

//这题老有名了,死了挺多。
思路:完全背包,二进制优化!!!(否则TLE)。

上代码:

#include<bits/stdc++.h>
using namespace std;
int b[6]={1,2,3,5,10,20};
int f[50001]={0};
int a[60000];
int ans,maxn,c,x;
int main(){
    for(int i=0;i<6;i++){//二进制优化,把物品拆成1,2,4,8,16的形式
        cin>>x;
        maxn=maxn+b[i]*x;
        int y=1;
        while (x>y){
            a[++c]=y*b[i];
            x-=y;
            y*=2;
        }
        a[++c]=x*b[i];
    }
    f[0]=1;
    for(register int j=1;j<=c;j++)
        for(register int g=maxn;g>=a[j];g--)
            f[g]=f[g-a[j]] || f[g];//直接01背包
    for(register int i=1;i<=maxn;i++)if(f[i])ans++;
    cout<<"Total="<<ans;
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/YFbing/p/9579055.html