【洛谷 P2347】砝码称重(多重背包可行性问题)

 P2347 砝码称重

题目描述

设有 1g1g 、 2g2g 、 3g3g 、 5g5g 、 10g10g 、 20g20g 的砝码各若干枚(其总重 \le 1000≤1000 ),

输入输出格式

输入格式:

输入方式: a_1 , a_2 ,a_3 , a_4 , a_5 ,a_6a1​,a2​,a3​,a4​,a5​,a6​

(表示 1g1g 砝码有 a_1a1​ 个, 2g2g 砝码有 a_2a2​ 个,…, 20g20g 砝码有 a_6a6​ 个)

输出格式:

输出方式: Total=NTotal=N

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

输入输出样例

输入样例#1: 复制

1 1 0 0 0 0

输出样例#1: 复制

Total=3

首先我们划定这些硬币所能表达出来的价值的范围应该是1~sum,sum即为背包的容量,这道题其实和楼教主的男人八题中的poj1742差不多(或者说这道题其实是那道题的缩水版,好像很多人暴力过了)。

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 100050;
int dp[maxn];
int re[maxn];
int v[maxn];
int sum[maxn];
int main()
{
    int a[7];
    int cnt=0;
    for(int i=1;i<=6;i++)
    {
        cin>>a[i];
    }
    v[1]=1,v[2]=2,v[3]=3,v[4]=5,v[5]=10,v[6]=20;
    int m=a[1]+2*a[2]+3*a[3]+5*a[4]+10*a[5]+20*a[6];
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    int ans=0;
    for(int i=1;i<=6;i++)
    {
        memset(sum,0,sizeof(sum));
        for(int j=v[i];j<=m;j++)
        {
            if(!dp[j]&&dp[j-v[i]]&&sum[j-v[i]]<a[i])
            {
                dp[j]=1;
                sum[j]=sum[j-v[i]]+1;
                ans++;
            }
        }
    }
    cout<<"Total="<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/duanghaha/article/details/81511612