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元钱最多可以用多少货币.每种货 ...
随机推荐
- Js模块化开发--seajs和gruntJs
1.Seajs库 解决开发中的冲突依赖等问题,提供代码可维护性. SeaJS 是由玉伯开发的一个遵循 CommonJS 规范的模块加载框架,可用来轻松愉悦地加载任意 JavaScript 模块和css ...
- Qt新安装之后出现Error while building/deploying (kit: Desktop Qt 5.7.0 GCC 64bit) When executing step "Make”
Ubuntu14.04初次安装Qt之后可能出现Error while building/deploying project *** (kit: Desktop Qt 5.7.0 GCC 64bit ...
- python:将numpy数组写入csv文件
import numpy as np np.savetxt('E:\\forpython\\featvector.csv',data_to_save,delimiter=',')
- koa 基础(十六)koa 中 session 的使用
1.app.js /** * koa 中 session 的使用 * 1.npm install koa-session --save * 2.const session = require('koa ...
- P2983 [USACO10FEB]购买巧克力
P2983 [USACO10FEB]购买巧克力 题解 注意题目开 long long 贪心策略:价格从低到高,买够为止 反证:若剩下的有一个K”,比K小,那么交换,稳赚不赔 所以,在买K之前,所有比他 ...
- RzPageControl(pagecontrol)实现多标签的动态添加,切换,关闭
https://blog.csdn.net/pdw2009/article/details/76157651 使用RzPageControl来实现多标签页使用菜单来打开标签页,通过标签页的captio ...
- LC 358. Rearrange String k Distance Apart
Given a non-empty string s and an integer k, rearrange the string such that the same characters are ...
- Session案例-用户登录场景
package com.loaderman.demo; import java.io.IOException; import java.io.PrintWriter; import javax.ser ...
- linux命令行下常用快捷键
快捷键的使用: ctrl+d或者使用logout.exit退出终端ctrl+a跳到开始ctrl+e跳到最后ctrl+u向前删除ctrl+k向后删除ctrl+c中断命令ctrl+z暂停命令 fg:将暂停 ...
- Pythoncookbook(数据结构与算法)在字典中将键映射到多个值上的方法
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法 本文实例讲述了Python在字典中将键映射到多个值上的方法.分享给大家供大家参考,具体如下: 问题:一个能将键(key ...