Q: 既是多重背包, 还是找零问题, 怎么处理?

A: 题意理解有误, 店主支付的硬币没有限制, 不占额度, 所以此题不比 1252 难多少

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.

题意:

John 去付款, 手上拿着各种面值的硬币, 每种面值的硬币有一个可以使用的上限, 店主支持找钱, 找钱所用的硬币是无限的

思路:

1. 证明背包的容量上限是个难点, 这里有个证明

http://www.cppblog.com/Davidlrzh/articles/135614.html

背包容量上限是 T + vmax^2

2. 使用倍增优化转化为 0/1 背包来做. 先求解 Jhon 的给钱方式, 再求解找钱方案, 两次 DP

3.  Jhon 的状态转移方程. dp[i][j] = min(dp[i][j], dp[i][j-w[i]]+1)

   店主的状态转移方程可以有两种表述, dp2[i][j] = min(dp2[i][j], dp2[i][j-w[i]]+1) (和 Jhon 的一样), 但是用到两个dp 数组

4. 第二种表述和 1252 相同, 仅使用一个dp 数组, 总的状态转移方程为 dp[j] = min([j-w[i]+1, dp[j+w[i]]+1);

总结:

1. 看别人的解题报告, 才知道店主找零的硬币是没有上限的, 这将题目的难度下降了很多, 难点就变成多重背包的优化了

2. 思路(3,4)的状态转移方程有误, 因为进行过倍增优化, 所以状态转移方程中并不是简单的+1, 而应该+倍增优化的倍数

3. 没判断输出为 INF 的情况, WA 了一次, 找到了测试用例地址

http://cerberus.delos.com:790/TESTDATA/DEC06_5.htm

代码:

#include <iostream>
using namespace std; int N,T;
int V[150], C[150];
int upload;
int dp[100000];
int stuff[10010];
int cnt[10010];
int len;
const int INF = 0X3F3F3F3F; /*
* 倍增优化转成 01 背包
* 处理 01 背包, 求解 Jhon 恰好付 v 元 所需要的硬币数
*/
void firstPass() {
len = 0;
for(int i = 0; i < N; i ++) {
int rem = C[i];
int j = 0; while(rem) { // 倍增优化转化成 01 背包
if(rem >= (1<<j)) {
stuff[len++] = V[i]*(1<<j);
cnt[len-1] = (1<<j);
rem -= (1<<j);
j++;
}else{
stuff[len++] = V[i]*rem;
cnt[len-1] = rem;
rem = 0;
}
}
} memset(dp, 0x3f, sizeof(int)*(upload+10));
dp[0] = 0;
for(int i = 0; i < len; i ++) {
for(int v = upload; v >= stuff[i]; v--) {
dp[v] = min(dp[v], dp[v-stuff[i]]+cnt[i]);
//printf("dp[%d], stuff[%d] = %d\n", v, i, stuff[i]);
}
}
} /*
* second pass 完全背包
* 状态转移方程, dp[v] = min(dp[v], dp[v+w[i]]+1)
* 要注意遍历顺序
*/
int secondPass() {
for(int i = 0; i < N; i ++) {
for(int v = upload-V[i]; v >= 0; v --) {
dp[v] = min(dp[v], dp[v+V[i]]+1);
}
}
return dp[T];
}
int main() {
freopen("E:\\Copy\\ACM\\测试用例\\in.txt", "r", stdin);
cin >> N >> T;
int vmax = 0;
int sum = 0;
for(int i = 0; i < N; i ++) {
scanf("%d", &V[i]);
vmax = max(vmax, V[i]);
}
upload = vmax*vmax + T; for(int i = 0; i < N; i ++) {
scanf("%d", &C[i]);
sum += C[i]*V[i];
}
if(sum < T)
cout << -1 << endl;
else {
firstPass();
int ans = secondPass();
if(ans != INF)
cout << secondPass() << endl;
else
cout << -1 << endl;
} return 0;
}

  

POJ 3260 The Fewest Coins(多重背包问题, 找零问题, 二次DP)的更多相关文章

  1. POJ 3260 The Fewest Coins(多重背包+全然背包)

    POJ 3260 The Fewest Coins(多重背包+全然背包) http://poj.org/problem?id=3260 题意: John要去买价值为m的商品. 如今的货币系统有n种货币 ...

  2. POJ 3260 The Fewest Coins(背包问题)

    [题目链接] http://poj.org/problem?id=3260 [题目大意] 给出你拥有的货币种类和每种的数量,商店拥有的货币数量是无限的, 问你买一个价值为m的物品,最少的货币流通数量为 ...

  3. POJ 3260 The Fewest Coins(完全背包+多重背包=混合背包)

    题目代号:POJ 3260 题目链接:http://poj.org/problem?id=3260 The Fewest Coins Time Limit: 2000MS Memory Limit: ...

  4. poj 3260 The Fewest Coins

    // 转载自http://blog.163.com/benz_/blog/static/18684203020115721917109/算法不难看出,就是一个无限背包+多重背包.问题在于背包的范围.设 ...

  5. POJ 1252 Euro Efficiency(完全背包, 找零问题, 二次DP)

    Description On January 1st 2002, The Netherlands, and several other European countries abandoned the ...

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

    题意:FJ身上有各种硬币,但是要买m元的东西,想用最少的硬币个数去买,且找回的硬币数量也是最少(老板会按照最少的量自动找钱),即掏出的硬币和收到的硬币个数最少. 思路:老板会自动找钱,且按最少的找,硬 ...

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

    The Fewest Coins DescriptionFarmer John has gone to town to buy some farm supplies. Being a very eff ...

  8. codevs 3961 硬币找零【完全背包DP/记忆化搜索】

    题目描述 Description 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资. 我们应该 ...

  9. [LeetCode] Coin Change 2 硬币找零之二

    You are given coins of different denominations and a total amount of money. Write a function to comp ...

随机推荐

  1. cocos2d-x 3.0点击响应

    迄今为止,发现cocos2d-x 3.0最让人惊艳的地方就是更改了点击事件机制.(ps:迄今只看了点击事件这块,捂嘴笑~~~) cocos2d-x 2.0 只有CCLayer有点击事件处理,需要注册, ...

  2. eclipse 项目中的java文件没有在WEB-INF目录下的classes中 生成相对应的编译后的类

    1.首先确定project->Build Automatically是否勾选上: 2.执行完第一步之后测试一下看是否能编译,如果还是不能,则进行手动编译:  3,进入clean对话框,选择Cle ...

  3. 使用B或BL跳转时,下一条指令的地址的计算

    .text .global _start 3_start: b step1 step1: ldr pc, =step2 step2: b step2 反汇编代码: : eaffffff b 0x4 : ...

  4. 使用 FreeRTOS 时注意事项总结(基础篇教程完结)

    以下转载自安富莱电子: http://forum.armfly.com/forum.php FreeRTOS 的初始化流程推荐的初始化流程如下,本教程配套的所有例子都是采用的这种形式,当然,不限制必须 ...

  5. am335x SGX 移植

    第一步,先安装对应的 PDK 包,并编译出相对应的kernel module. 我是在 PDK 3.0 上面进行开发的,所以要先把相对应的 PDK包. 下载地址: http://software-dl ...

  6. windows server 2008 域控安装

    windows server 2008 域控安装:1.dns安装,安装过程会提示.net frame 3.51安装 3.域控安装 原文:地址 http://wenku.baidu.com/link?u ...

  7. java-jdbc循环设置sql参数

    PreparedStatement sta=null; Connection conn=null; @Test public void Test2() { //获取连接池 ComboPooledDat ...

  8. 常用的经典jquery代码[转]

    0. 如何创建嵌套的过滤器: //允许你减少集合中的匹配元素的过滤器, //只剩下那些与给定的选择器匹配的部分.在这种情况下, //查询删除了任何没(:not)有(:has) //包含class为“s ...

  9. javascript文本格式化之HTML标签(转载)

    文本格式化标签: 标签 描述 <b> 定义粗体文本. <big> 定义大号字. <em> 定义着重文字. <i> 定义斜体字. <small> ...

  10. bcm53344 gpio驱动分析

    /********************************************************************************* * 1.查看代码是在vim下,使用 ...