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元钱最多可以用多少货币.每种货 ...
随机推荐
- 3.Linux系统文件名字体不同的颜色都代表什么
在Linux中,文件的颜色都是有含义的.其中, Linux中文件名颜色不同,代表文件类型不一样.如下所示: 白色:表示普通文件浅蓝色:表示链接文件: 灰色:表示其他文件: 绿色:表示可执行文件: 红色 ...
- 谷歌protocolbuff使用说明步骤
Protocolbuff 目录 1 Protocolbuff定义和作用... 1 2 Protocolbuff的使用步骤... 1 3 .proto编写格式... ...
- 2.1 MATLAB的数据类型
2.1 MATLAB的数据类型 每种数据类型都是以矩阵的形式存在的 数据类型:数值型.字符型.元胞型.结构体.函数句柄 数值型包含:双精度类型.单精度类型.整型 支持不同数据的转换 2.1.1 变量与 ...
- LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
题目描述 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解题思路 二叉树转化为链表的基本 ...
- EBS GL 日记账行“账户说明”段说明显示不全
问题描述: 路径:总帐管理超级用户/日记帐/输入 如下图所示,日记账行的“账户说明字段”段值说明显示不全 解决方法: 路径:总帐管理超级用户/设置/财务系统/弹性域/关键字/段 如下图所示,找到相应的 ...
- android data binding jetpack I 环境配置 model-view 简单绑定
android data binding jetpack VIII BindingConversion android data binding jetpack VII @BindingAdapter ...
- android下载网络图片,设置宽高,等比缩放
使用Picasso组件去下载图片会发现图片宽高会变形不受等比缩放控制,即使设置了图片的 scaleType,可能是对Picasso的api没有用对, Picasso.with(this.activit ...
- java代码实现将集合中的重复元素去掉
package com.loaderman.test; import java.util.ArrayList; import java.util.LinkedHashSet; import java. ...
- php中应用redis
下载软件包wget https://codeload.github.com/phpredis/phpredis/zip/develop mv develop phpredis.zip 解压unzip ...
- go中的数据结构-字典map
1. map的使用 golang中的map是一种数据类型,将键与值绑定到一起,底层是用哈希表实现的,可以快速的通过键找到对应的值. 类型表示:map[keyType][valueType] key一定 ...