hdu 1709 求天平不能称重的重量 动态规划

给定一个天平和n个砝码,每个砝码都有一个重量,求出从1到这些砝码的总和之间不能被天平表示的重量。天平可以两端放砝码。

动态规划做法,看网上都是母函数,真心不懂。。

dp[i]如果是0表示这些砝码不能称重i重量,如果是1表示能称重i重量。

对于每个砝码,假设当前砝码重量是b[i],那么j从最大值开始,减小到b[i],

如果存在一个dp[j-b[i]]为1,说明当前的j能被组成。

j逆着循环的原因是由于每个砝码只有 一个,类似于01背包与完全背包的样子,

如果正向循环会导致每个物品可能使用多次,逆向循环则不会出现这个问题。

其实举个例子就能看出来了。

因为天平是可以两边放的,因此可以从大的数中减去小的数,方法就是对于每个砝码重量b[i],

遍历在dp数组中为真的并且比b[i]那些j,那么dp[j-b[i]]也一定为真,这个乍一看不靠谱,但经过分析好像是对的。

如果b[i]被重复使用了怎么办?即dp[j]已经使用了b[i]了,你还要减去b[i],但它只有一个啊。

此时如果dp[j]已经使用了b[i],那么dp[j-b[i]]早已经为真了,即由别的砝码早可以组成dp[j-b[i]]了。

如果是多个砝码减2个砝码怎么办?不会漏掉吗?其实在第一个砝码的时候就记录了多个砝码减第一个砝码的结果,

到第二个砝码的时候会用到这个结果。这样就不会漏了。

其实这也是dp,这个dp的j要正向进行,逆向进行就会导致砝码重复使用。

#include<bitset>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<set>
#define inf 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;

inline int in()
{
    int res=0;
    char c;
    while((c=getchar())<'0' || c>'9');
    while(c>='0' && c<='9')res=res*10+c-'0',c=getchar();
    return res;
}

const int N=100006;
int dp[N];
int b[2006];

int ans[20000];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        mem(dp,0);
        int mx=0;
        for(int i=0;i<n;i++)
        {
            b[i]=in();
            mx+=b[i];
        }

        dp[0]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=mx;j>=b[i];j--)
            {
                if(dp[j-b[i]]) dp[j]=1;
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=b[i];j<=mx;j++)
            {
                if(dp[j])dp[j-b[i]]=1;  //每个比当前砝码大的,减去当前砝码的重量。
            }
        }
        int p=0;
        for(int i=1;i<=mx;i++)if(!dp[i])ans[p++]=i;
        printf("%d\n",p);
        for(int i=0;i<p-1;i++)
        {
            printf("%d ",ans[i]);
        }
        if(p>0)printf("%d\n",ans[p-1]);  //当时又漏了p>0

    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 14:39:25

hdu 1709 求天平不能称重的重量 动态规划的相关文章

HDU 1709 母函数天平问题 可出现减法的情况 The Balance

The Balance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6652    Accepted Submission(s): 2730 Problem Description Now you are asked to measure a dose of medicine with a balance and a number o

天平称重

1. 给你 8 颗小石头和一架天平.其中有 7 颗石头重量是一样的,另外一个比这 7 颗略重.请问在最坏的情况下,最少要称几次,才能把这颗较重的石头找出来. 首先任取其中6个小石头一边3个进行称重,如果重量相等,再称剩下两个即可找出重的:如果不相等,取较重的一边的任意2个称重,如相等则剩下的1个是重球,如不相等则较重的是. 3+3,如果相等,剩下2个一次OK:如果不相等,较重的3个采取1+1,如果相等,剩下的1个即为结果,否则1+1中较重的1个即为结果. 2. 12球问题是指有十二个球,其中十一

枚举 天平称重

天平称重 [问题描述] 用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量. 如果只有5个砝码,重量分别是1,3,9,27,81 则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中). 本题目要求编程实现:对用户给定的重量,给出砝码组合方案. 例如: 用户输入: 5 程序输出: 9-3-1 用户输入: 19 程序输出: 27-9+1 要求程序输出的组合总是大数在前小数在后. 可以假设用户的输入的数字符合范围1~121. 题解:所有的天平,可以分为 减,不加,加,也就

*HDU 1709 母函数

The Balance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7677    Accepted Submission(s): 3187 Problem Description Now you are asked to measure a dose of medicine with a balance and a number o

天平砝码称重量

源blog地址http://onlywish.me 用天平称重量 有1,3,9,27,81的砝码 输入一个121以内的数.求出称重方法: 如:输入10 显示 9+1: 输入 7  显示 9-3+1; 下面是答案(自己写的,非标准): #include <stdio.h> #include <math.h> int sum = 0; int array[5] = {1,3,9,27,81}; int count[5] = {1,4,13,40,121}; char jo[2][2]

砝码称重3

参考 https://blog.csdn.net/livelylittlefish/article/details/6555347 假设有280g盐,有一架天平,有两个砝码,分别是4g和14g .能否在3次内将280g食盐分为100g和180g两堆,请详细描述你的解决方法. 这是另外一种砝码称重问题,类似,但是又不同.砝码称重这个是给定无限数量砝码,只需计算能不能组成一个重量,不用知道如何组合.砝码称重1是给定砝码个数和重量,以及可以组合的重量,求出任意一种重量是如何组合的.砝码称重2给定重量和

Hdu 1709 The Balance

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1709 题意: 给N个整数,每个数只能使用一次.将他们组合起来,最后看在1~sum(a[1]..a[N])这些数里有多少数是这N个数组合不出来的. 先输出这些数的个数,再将这些数输出来.如果个数是0,那么不需要输出数. 案例分析: input: 3 1 2 4 output: 0 -->1(||4-1-2) , 2(||4-2) , 1+2(||4-1) , 4  , 1+4 , 2+4 , 1+2+

【dp】砝码称重

砝码称重 来源:NOIP1996(提高组)  第四题 [问题描述]     设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000),用他们能称出的重量的种类数. [输入文件]   a1  a2  a3  a4  a5  a6     (表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个,中间有空格). [输出文件]   Total=N     (N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况). [输入样例]     1 1 0 0 0

砝码称重问题二

题目描述 有一组砝码,重量互不相等,分别为m1.m2.m3……mn:它们可取的最大数量分别为x1.x2.x3……xn. 现要用这些砝码去称物体的重量,问能称出多少种不同的重量. 现在给你两个正整数列表w和n, 列表w中的第i个元素w[i]表示第i个砝码的重量,列表n的第i个元素n[i]表示砝码i的最大数量.  i从0开始                   请你输出不同重量的种数.如:w=[1,2], n=[2,1], 则输出5(分析:共有五种重量:0,1,2,3,4) 解题 参考智力题砝码称重