完全背包(硬币)

http://acm.hdu.edu.cn/showproblem.php?pid=1114

Piggy-Bank

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 43171    Accepted Submission(s): 21299

Problem Description

Before
ACM can do anything, a budget must be prepared and the necessary
financial support obtained. The main income for this action comes from
Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some
ACM member has any small money, he takes all the coins and throws them
into a piggy-bank. You know that this process is irreversible, the coins
cannot be removed without breaking the pig. After a sufficiently long
time, there should be enough cash in the piggy-bank to pay everything
that needs to be paid.

But there is a big problem with
piggy-banks. It is not possible to determine how much money is inside.
So we might break the pig into pieces only to find out that there is not
enough money. Clearly, we want to avoid this unpleasant situation. The
only possibility is to weigh the piggy-bank and try to guess how many
coins are inside. Assume that we are able to determine the weight of the
pig exactly and that we know the weights of all coins of a given
currency. Then there is some minimum amount of money in the piggy-bank
that we can guarantee. Your task is to find out this worst case and
determine the minimum amount of cash inside the piggy-bank. We need your
help. No more prematurely broken pigs!

Input

The
input consists of T test cases. The number of them (T) is given on the
first line of the input file. Each test case begins with a line
containing two integers E and F. They indicate the weight of an empty
pig and of the pig filled with coins. Both weights are given in grams.
No pig will weigh more than 10 kg, that means 1 <= E <= F <=
10000. On the second line of each test case, there is an integer number N
(1 <= N <= 500) that gives the number of various coins used in
the given currency. Following this are exactly N lines, each specifying
one coin type. These lines contain two integers each, Pand W (1 <= P
<= 50000, 1 <= W <=10000). P is the value of the coin in
monetary units, W is it‘s weight in grams.

Output

Print
exactly one line of output for each test case. The line must contain
the sentence "The minimum amount of money in the piggy-bank is X." where
X is the minimum amount of money that can be achieved using coins with
the given total weight. If the weight cannot be reached exactly, print a
line "This is impossible.".

Sample Input

3
10 110
2
1 1
30 50
10 110
2
1 1
50 30
1 6
2
10 3
20 4

Sample Output

The minimum amount of money in the piggy-bank is 60.
The minimum amount of money in the piggy-bank is 100.
This is impossible.

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
using namespace std;
typedef long long ll ;

struct node
{
    int val , w ;
    double temp ;
}a[509];

int dp[10009];

int main()
{
    int t ;
    cin >> t ;
    while(t--)
    {
        int k , m , n  ;
        scanf("%d%d" , &k , &m);
        m = m - k ;
        scanf("%d" , &n) ;
        for(int i = 1 ; i <= n ; i++)
        {
            scanf("%d%d" , &a[i].val , &a[i].w);
        }
        for(int i = 1 ; i <= 10009 ; i++)
            dp[i] = INF ;
        dp[0] = 0 ;
        for(int i = 1 ; i <= n ; i++)
        {
            for(int j = a[i].w ; j <= m ; j++)
            {
                dp[j] = min(dp[j] , dp[j-a[i].w]+a[i].val);
            }
        }
        if(dp[m] == INF)
            cout << "This is impossible." << endl ;
        else
        {
            cout << "The minimum amount of money in the piggy-bank is " << dp[m] << "." << endl ;
        }

    }

    return 0;
}

原文地址:https://www.cnblogs.com/nonames/p/11706429.html

时间: 2024-10-31 14:28:03

完全背包(硬币)的相关文章

dp背包问题/01背包,完全背包,多重背包,/coin change算法求花硬币的种类数

一步一步循序渐进. Coin Change 具体思想:给你 N元,然后你有几种零钱S={S1,S2...,Sm} (每种零钱数量不限). 问:凑成N有多少种组合方式  即N=x1 * S1+x2*S2+...+xk*Sk (xk>=0,k=1,2..m) 设有f(x)中组合方式 有两种解答(自底向上回溯): 1.不用第m种货币   f(N,m-1) 2.用第m种货币 f(N-Sm,m) 总的组合方式为f(N,m)=f(N,m-1)+f(N-Sm,m) anything is nonsense,s

[BZOJ 1042][HAOI 2008]硬币购物(背包+容斥原理)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1042 刚开始搞容斥原理,还很有点吃力,我太弱了... 首先用被类似于背包的DP进行预处理,假设每种硬币个数无限制,求出f[i]=凑出面值i的方案总数. 但是实际上题目中每种硬币个数是有限制的,设四种硬币分别是a.b.c.d,则凑出面值S的方案中超出限制的方案数=a超出限制的方案数+b超出限制的方案数+c超出限制的方案数+d超出限制的方案数-a和b都超出限制的方案数-a和c都超出限

BZOJ 1042 硬币购物(完全背包+DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1042 题意:给出四种面值的硬币c1,c2,c3,c4.n个询问.每次询问用d1.d2.d3.d4个相应的硬币能够拼出多少种总和为s? 思路:(1)首先,用完全背包求出f[i]表示四种硬币的数量无限制拼出i的方案数. (2)接着我们来理解 x=f[s]-f[s-(d1+1)*c1]的含义:x表示c1硬币的数量不超过d1个而其他三种硬币的数量不限制拼成s的方案数.我们举着例子来说明, 假设

背包的硬币问题

转自 http://www.cnblogs.com/qiufeihai/archive/2012/09/11/2680840.html 首先说没限制的硬币问题吧: 先看这个问题:在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. 我们用dp[n]表示用这些硬币组成n的方法总数.... 然后随着硬币种类的增加来更新dp[]的值,也就是最外面的一层循环for(i :1-->3)开始初始化的时候没有硬币,然后新来了面值为1的硬币,接着又来了面值为2的硬币

【bzoj1042】[HAOI2008]硬币购物 背包dp+容斥原理

题目描述 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 输入 第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000 输出 每次的方法数 样例输入 1 2 5 10 2 3 2 3 1 10 1000 2 2 2 900 样例输出 4 27 题解 背包dp+容斥原理 考虑没有硬币个数限制,那么本题显然是完全

UVA 674 Coin Change 硬币转换(完全背包,常规)

题意:有5种硬币,个数无限的,组成n元的不同方案有多少种? 思路:常规完全背包.重点在dp[0]=1,dp[j]中记录的是组成 j 元的方案数.状态转移方程dp[j+coin[i]]+=dp[j]. 1 #include <bits/stdc++.h> 2 using namespace std; 3 int coin[]={1, 5, 10, 25, 50}; 4 int dp[10000], n; 5 6 int cal() 7 { 8 if(!n) return 1; 9 memset(

bzoj1708:[Usaco2007 Oct]Money奶牛的硬币(完全背包

1708: [Usaco2007 Oct]Money奶牛的硬币 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 797  Solved: 540[Submit][Status][Discuss] Description 在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币系统中,硬币的面值通常是1,5,10,20或25,50,以及100单位的货币,有时为了更方便地交易,会发行面值为2单位

硬币问题 (dp,多重背包的二分优化)

题目描述 给你n种硬币,知道每种的面值Ai和每种的数量Ci.问能凑出多少种不大于m的面值. 输入 有多组数据,每一组第一行有两个整数 n(1≤n≤100)和m(m≤100000),第二行有2n个整数,即面值A1,A2,A3,…,An和数量C1,C2,C3,…,Cn (1≤Ai≤100000,1≤Ci≤1000).所有数据结束以2个0表示. 输出 每组数据输出一行答案. 样例输入 3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0 样例输出 8 4 背包问题的复杂度是n*m,这题如果

UVA 562 Dividing coins 分硬币(01背包,简单变形)

题意:一袋硬币两人分,要么公平分,要么不公平,如果能公平分,输出0,否则输出分成两半的最小差距. 思路:将提供的整袋钱的总价取一半来进行01背包,如果能分出出来,就是最佳分法.否则背包容量为一半总价的包能装下的硬币总值就是其中一个人能分得的最多的钱了,总余下的钱减去这包硬币总值.(只需要稍微考虑一下总值是奇数/偶数的问题) 1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #includ

POJ 3260 The Fewest Coins 最少硬币个数(完全背包+多重背包,混合型)

题意:FJ身上有各种硬币,但是要买m元的东西,想用最少的硬币个数去买,且找回的硬币数量也是最少(老板会按照最少的量自动找钱),即掏出的硬币和收到的硬币个数最少. 思路:老板会自动找钱,且按最少的找,硬币数量也不限,那么可以用完全背包得出组成每个数目的硬币最少数量.而FJ带的钱是有限的,那么必须用多重背包,因为掏出的钱必须大于m,那么我们所要的是大于等于m钱的硬币个数,但是FJ带的钱可能很多,超过m的很多倍都可能,那么肯定要有个背包容量上限,网上说的根据抽屉原理是m+max*max,这里的max指