Charlie's Change POJ - 1787
|
Time limit |
1000 ms |
| Memory limit | 30000 kB |
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 numbers and types of coins Charlie has and the coffee price. The coffee vending machines accept coins of values 1, 5, 10, and 25 cents. The program should output which coins Charlie has to use paying the coffee so that he uses as many coins as possible. Because Charlie really does not want any change back he wants to pay the price exactly.
input
Each line of the input contains five integer numbers separated by a single space describing one situation to solve. The first integer on the line P, 1 <= P <= 10 000, is the coffee price in cents. Next four integers, C1, C2, C3, C4, 0 <= Ci <= 10 000, are the numbers of cents, nickels (5 cents), dimes (10 cents), and quarters (25 cents) in Charlie's valet. The last line of the input contains five zeros and no output should be generated for it.
For each situation, your program should output one line containing the string "Throw in T1 cents, T2 nickels, T3 dimes, and T4 quarters.", where T1, T2, T3, T4 are the numbers of coins of appropriate values Charlie should use to pay the coffee while using as many coins as possible. In the case Charlie does not possess enough change to pay the price of the coffee exactly, your program should output "Charlie cannot buy coffee.".
sample input
12 5 3 1 2
16 0 0 0 1
0 0 0 0 0
sample output
Throw in 2 cents, 2 nickels, 0 dimes, and 0 quarters.
Charlie cannot buy coffee.
题目解读
代码思路是看别的代码得到的,对其代码进行了优化并加了自己的注释,其中利用了映射来加强练习。
总体来说,就是个多重背包加上路径记忆。
代码区
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
const int M = 10003;
const int INF = 0x3f3f3f3f;
map<int, int>num, val;
int dp[M], used[M], path[M]; //dp[i]表示凑齐价值 i 时所用的最大硬币数量
//used[i]表示在价值 i 时已经用了当前种类硬币数量
//path[i] 下标表示当前价值, 值表示凑成价值 i 之前的总价值,即用了
//某一硬币之前的价值, i - path[i] 则表示这一过程中使用的硬币价值
int main()
{
int p ,c1 ,c2,c3,c4;
while(cin>>p>>c1>>c2>>c3>>c4)
{
if (p + c1 + c2 + c3 + c4 == 0)break;
num[1] = c1;
num[2] = c2;
num[3] = c3;
num[4] = c4;
val[1] = 1;
val[2] = 5;
val[3] = 10;
val[4] = 25; //练习一下映射
memset(path, 0, sizeof(path)); //路径初始化
for(int i = 1 ;i <= p ; i ++)
{
dp[i] = -INF;
}
dp[0] = 0; //基础部分,将除了起点设置为0外,其余的初始值均为负无穷大,
//意味着某一状态只有从起点开始转移,其值才有效
for (int i = 1; i <= 4; i++)
{
memset(used, 0, sizeof(used)); //初始化各个价值的硬币使用数
for(int j = val[i] ; j<= p ; j++)
{
if (used[j - val[i]] < num[i] && dp[j-val[i]] >=0 && dp[j - val[i]] + 1 > dp[j])
//硬币数量足够转移,且转移后的硬币数量更多,以及转移的前一个状态有效
{
dp[j] = dp[j - val[i]] + 1; //表示从前一个状态转移过来
used[j] = used[j - val[i]] + 1; //表示从 j - val[i] 价值转移而来用了一个硬币
path[j] = j - val[i]; //下标表示当前价值,其值表示转移起点的价值
}
}
}
if(dp[p] < 0) //若dp[i]<0表示这一价值无法凑齐
{
cout << "Charlie cannot buy coffee." << endl;
continue;
}
map<int, int>ans;
ans[1] = 0;
ans[5] = 0;
ans[10] = 0;
ans[25] = 0; //代表各个价值对应的硬币的使用数量
int now = p; //从终点开始回溯
while(true)
{
if (now == 0)break; //价值为0 ,代表已经走回了起点
ans[now - path[now]]++; //now - path[now] 表示两个状态之间的差值,此差值就是各个硬币的价值,所以对应价值的硬币数量加一
now = path[now]; //为下一次做准备
}
printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n", ans[1], ans[5], ans[10], ans[25]);
}
return 0;
}
Charlie's Change POJ - 1787的更多相关文章
- (多重背包+记录路径)Charlie's Change (poj 1787)
http://poj.org/problem?id=1787 描述 Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie dri ...
- poj 1787 Charlie's Change (多重背包可作完全背包)
Charlie's Change Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3792 Accepted: 1144 ...
- poj 1787 背包+记录路径
http://poj.org/problem?id=1787 Charlie's Change Time Limit: 1000MS Memory Limit: 30000K Total Subm ...
- 专题复习--背包问题+例题(HDU 2602 、POJ 2063、 POJ 1787、 UVA 674 、UVA 147)
*注 虽然没什么人看我的博客但我还是要认认真真写给自己看 背包问题应用场景给定 n 种物品和一个背包.物品 i 的重量是 w i ,其价值为 v i ,背包的容量为C.应该如何选择装入背包中的物品,使 ...
- Charlie's Change(完全背包+路径记忆)
Charlie's Change Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3176 Accepted: 913 D ...
- Charlie's Change(完全背包记录路径)
Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he often buys coffe ...
- B - Charlie's Change
Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he often buys coffe ...
- poj1787 Charlie's Change
Description Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he ofte ...
- [POJ 1787]Charlie's Change (动态规划)
题目链接:http://poj.org/problem?id=1787 题意:有4种货币分别是1元,5元,10元,20元.现在告诉你这四种货币分别有多少个,问你正好凑出P元钱最多可以用多少货币.每种货 ...
随机推荐
- python多环境切换,pyenv的使用
1.安装pyenv:https://github.com/pyenv/pyenv-installer curl -L https://github.com/pyenv/pyenv-installer/ ...
- Android中的“再按一次返回键退出程序”代码实现
1 用户在退出应用前给出一个提示是很有必要的,因为可能是用户并不真的想退出,而只是一不小心按下了返回键,大部分应用也是这么做的,但也有些应用的做法是在应用退出去前给出一个Dialog,我觉得这样不太友 ...
- CodeForces - 369E Valera and Queries(树状数组)
CodeForces - 369E Valera and Queries 题目大意:给出n个线段(线段的左端点和右端点坐标)和m个查询,每个查询有cnt个点,要求给出有多少条线段包含至少其中一个点. ...
- 19.Python转义字符及用法
在前面的章节中,我们曾经简单学习过转义字符,所谓转义,可以理解为“采用某些方式暂时取消该字符本来的含义”,这里的“某种方式”指的就是在指定字符前添加反斜杠 \,以此来表示对该字符进行转义. 举个例子, ...
- html基础(img、a、列表 )
图片标签(img) <img src="图片路径" alt="图片描述 图片无法正常显示出现文字" title="爱你"/> i ...
- 6 Java Shell排序
希尔排序是先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序. 1.基本思想 将待排序数组按照步长gap进行分组,然后将 ...
- readerwriterqueue 一个用 C++ 实现的快速无锁队列
https://www.oschina.net/translate/a-fast-lock-free-queue-for-cpp?cmp&p=2 A single-producer, sing ...
- centos6一键安装WordPress
#!/bin/bash service iptables stop setenforce yum -y install httpd service httpd restart yum -y insta ...
- Break 和 Continue 标签 kotlin(12)
Break 和 Continue 标签 在 Kotlin 中任何表达式都可以用标签(label ) 来标记. 标签的格式为标识符后跟 @ 符 号,例如: abc@ . fooBar@ 都是有效的标签( ...
- 左键双击关闭pagecontrol中的一个分页即一个tabsheet,功能像遨游浏览器一样
左键双击关闭pagecontrol中的一个分页即一个tabsheet,功能像遨游浏览器一样 procedure TfrmServerSetup.PageControl1MouseDown(Sender ...