POJ3260——背包DP(多重)——The Fewest Coins

Description

Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of coins he receives in change is minimized. Help him to determine what this minimum number is.

FJ wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1V2, ..., VN (1 ≤ Vi≤ 120). Farmer John is carrying C1 coins of value V1C2 coins of value V2, ...., and CN coins of value VN (0 ≤ Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner (although Farmer John must be sure to pay in a way that makes it possible to make the correct change).

Input

Line 1: Two space-separated integers: N and T
Line 2: N space-separated integers, respectively V1V2, ..., VN coins ( V1, ... VN
Line 3: N space-separated integers, respectively C1C2, ..., CN

Output

Line 1: A line containing a single integer, the minimum number of coins involved in a payment and change-making. If it is impossible for Farmer John to pay and receive exact change, output -1.

Sample Input

3 70
5 25 50
5 2 1

Sample Output

3

Hint

Farmer John pays 75 cents using a 50 cents and a 25 cents coin, and receives a 5 cents coin in change, for a total of 3 coins used in the transaction.

大意:让你找钱,最少流通的货币,买东西时货币有限制,找钱的时候货币没限制,多重背包问题用二进制01背包轻松解决,用函数来写清楚多了~

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 50010;
const int inf = 0x3f3f3f3f;
int dp[50010];
int w[110],num[110];
int n,m;
void oneback(int w,int v){
    for(int i =  MAX ; i >= w; i--)
        dp[i] = min(dp[i],dp[i-w]+v);
}
void comback(int w,int v){
    for(int i = MAX+w ; i>= 0; i--)
        dp[i] = min(dp[i],dp[i-w]+v);
}
int multiplepack()
{
    int k ;
    for(int i = 1; i <= MAX; i++)
        dp[i] =inf;
    dp[0] = 0;
    for(int i = 1; i <= 2*n;i ++){
        if( i <= n){
             k = 1;
            while(k < num[i]){
                oneback(k*w[i],k);
                num[i] -= k;
                k*= 2;
            }
            oneback(num[i]*w[i],num[i]);
        }
        else
            comback(-w[i-n],1);
    }
    if(dp[m] == inf)
        return -1;
    else return dp[m];
}
int main()
{
    while(~scanf("%d%d",&n,&m)){
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n ; i++)
            scanf("%d",&w[i]);
        for(int i = 1; i <= n ; i++)
            scanf("%d",&num[i]);
        printf("%d\n",multiplepack());
    }
    return 0;
}

时间: 2024-08-03 03:10:51

POJ3260——背包DP(多重)——The Fewest Coins的相关文章

POJ3260——The Fewest Coins(多重背包+完全背包)

The Fewest Coins DescriptionFarmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus

poj 3260 The Fewest Coins 多重背包+完全背包

题目链接:http://poj.org/problem?id=3260 给店家的钱是多重背包 dp[] 店家的找钱是完全背包 dp2[] 然后最后 其中i表示多给了多少钱 也就是需要找回多少钱 int ans = INF; ans = min(ans, dp[m+i] + dp2[i]); 是一个比较简单的思路 神坑题 看到每种货币的面值不大于120 我就觉得找钱一定不会超过119块钱结果wa到死 后来才发现不是的啊 之所以我有这种思维定式是因为现实生活中有1块钱这种货币单位 考虑一种极限的情况

POJ 1742 Coins ( 经典多重部分和问题 &amp;&amp; DP || 多重背包 )

题意 : 有 n 种面额的硬币,给出各种面额硬币的数量和和面额数,求最多能搭配出几种不超过 m 的金额? 分析 : 这题可用多重背包来解,但这里不讨论这种做法. 如果之前有接触过背包DP的可以自然想到DP数组的定义 ==> dp[i][j] 表示使用前 i 种硬币是否可以凑成面额 j . 根据这样的定义,则一开始初始化 dp[0][0] = true 最后统计 dp[n][1 ~ m] 为 true 的数量即为答案 状态转移方程为 dp[i][j] |= dp[i-1][ j - k*val[i

POJ3260The Fewest Coins[背包]

The Fewest Coins Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6299   Accepted: 1922 Description Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the sm

poj1014 dp 多重背包

1 //Accepted 624 KB 16 ms 2 //dp 背包 多重背包 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 using namespace std; 7 const int imax_n = 120005; 8 int f[imax_n]; 9 int amount[7]; 10 int v; 11 int n=6; 12 int max(int a,int b) 1

POJ-3260 The Fewest Coins

题目链接:POJ-3260 题意是一个人买东西,有n种纸币,面额为v[i],数量为c[i].同时售货员也有这些纸币,数量为无限.要买价值为t的东西,希望给"钱用的纸币数和着钱用的纸币数的和"最少. 思路很显然是完全背包和多重背包各处理售货员和这位老哥.这个题给出所有v[i]<=120,这一点很有迷惑性. 一开始我的做法是把上界设成t+120,但是发现这样的做法是不多的.网上给出的做法是设上界为maxv*maxv+t.证明过程如下: 要凑足(大于等于)价格T的商品且硬币数最少,最多

【bzoj1531】[POI2005]Bank notes 多重背包dp

题目描述 Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有n种面值的硬币,面值分别为b1, b2,..., bn. 但是每种硬币有数量限制,现在我们想要凑出面值k求最少要用多少个硬币. 输入 第一行一个数 n, 1 <= n <= 200. 接下来一行 n 个整数b1, b2,..., bn, 1 <= b1 < b2 < ... < b n <= 20 000, 第三行 n 个整数c1, c2,..., cn, 1 <

POJ1787——背包DP(特定状态+回溯)——Charlie&#39;s Change

Description Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he often buys coffee at coffee vending machines at motorests. Charlie hates change. That is basically the setup of your next task. Your program will be given

混合背包(多重背包+完全背包)—— POJ 3260

对应POJ题目:点击打开链接 The Fewest Coins Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5450   Accepted: 1653 Description Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a