Too Rich

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1666    Accepted Submission(s): 422

Problem Description
You are a rich person, and you think your wallet is too heavy and full now. So you want to give me some money by buying a lovely pusheen sticker which costs pdollars from me. To make your wallet lighter, you decide to pay exactly p dollars by as many coins and/or banknotes as possible.

For example, if p=17 and you have two $10 coins, four $5 coins, and eight $1 coins, you will pay it by two $5 coins and seven $1 coins. But this task is incredibly hard since you are too rich and the sticker is too expensive and pusheen is too lovely, please write a program to calculate the best solution.

 
Input
The first line contains an integer T indicating the total number of test cases. Each test case is a line with 11 integers p,c1,c5,c10,c20,c50,c100,c200,c500,c1000,c2000, specifying the price of the pusheen sticker, and the number of coins and banknotes in each denomination. The number ci means how many coins/banknotes in denominations of i dollars in your wallet.

1≤T≤20000
0≤p≤109
0≤ci≤100000

 
Output
For each test case, please output the maximum number of coins and/or banknotes he can pay for exactly p dollars in a line. If you cannot pay for exactly p dollars, please simply output '-1'.
 
Sample Input
3
17 8 4 2 0 0 0 0 0 0 0
100 99 0 0 0 0 0 0 0 0 0
2015 9 8 7 6 5 4 3 2 1 0
 
Sample Output
9
-1
36
 
Source
 
听说是一个金牌题,确实很巧妙。
开始的想法是,多重背包,用二进制优化成01背包,d[i] :钱币为 i 的最多钱币数目,但是开不了这么大的数组,用map映射一下,或者改成记忆化搜索写法,但是是不可能的,记忆化还是得有一个vis数组~~~。
 
 
正解:
先转换思路,凑P求最多硬币,转为求mon - P 的最少硬币数。
然后贪心,但是会像记忆化搜索一样要回溯。直接贪心不太好。但是,硬币问题有一个特点,如果所有的钱币如: 1  ,   5   ,   10  ,   20  , 40   ,   80  ,   800,你已经看出来了,就是这种前面是后面的因子,这样就不可能说要从后往前的过程中要回溯。直接从后往前贪心。
 
怎么转为这种情况呢,发现只要改变两个数  50,500,改成 100,1000来用,就可以了。
#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;

int c[];
int v[] = {,,,,,,,,,};
int num[];
int sum,mon,p,ans; int solve(int x) {
int ret = ,need; for(int i = ; i >=; i--) { if(v[i]==) {
need = x/;
need = min(need,num[i]/);
ret +=*need;
x-=need*;
}
else if(v[i]==) {
need = x/;
need = min(need,num[i]/);
ret +=*need;
x-=need*;
}
else {
need = x/v[i];
need = min(need,num[i]);
ret +=need;
x -=need*v[i];
}
}
if(x) return inf;
return ret; } int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--) { sum = mon = ;
scanf("%d",&p);
for(int i = ; i < ; i++) {
scanf("%d",&num[i]);
sum +=num[i];
mon +=num[i]*v[i];
} p = mon - p; //最少的硬币去兑换 if(p<) {
puts("-1");
continue;
} ans = inf;
ans = min(ans,solve(p)); if(num[]) {
p-=;num[]--;
if(p>=)
ans = min(ans,solve(p)+);
p+=;num[]++;
}
if(num[]) {
p-=;num[]--;
if(p>=)
ans = min(ans,solve(p)+);
p+=;
num[]++;
}
if(num[]&&num[]) {
p-=;num[]--;num[]--;
if(p>=)
ans = min(ans,solve(p)+);
}
if(ans==inf) puts("-1");
else printf("%d\n",sum-ans);
} return ;
}
 

HDU 5527 贪心的更多相关文章

  1. 【算法系列学习】HDU 5527 Too Rich贪心

    http://www.cnblogs.com/AOQNRMGYXLMV/p/4934747.html #include<iostream> #include<cstdio> # ...

  2. Too Rich HDU - 5527 (贪心+dfs)

    Too Rich Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  3. HDU 5527 Too Rich 贪心

    题意: 有\(10\)种面值为\(1, 5, 10, 20, 50, 100, 200, 500, 1000, 2000\)的纸币,现在你要选最多的数量凑成\(p\)块钱. 分析: 同样分析问题的反面 ...

  4. HDU 5527 Too Rich ( 15长春区域赛 A 、可贪心的凑硬币问题 )

    题目链接 题意 : 给出一些固定面值的硬币的数量.再给你一个总金额.问你最多能用多少硬币来刚好凑够这个金额.硬币数量和总金额都很大   分析 : 长春赛区的金牌题目 一开始认为除了做类似背包DP那样子 ...

  5. HDU 5527:Too Rich(DFS+贪心)***

    题目链接 题意 给出p块钱,现在要用十种硬币凑出,每种硬币有c[i]个,问最多能用多少个硬币. 思路 首先确定,对于每个硬币就是能用小的替换就不用大的. 所以,可以先把硬币尽量用小的替换,如果小的不够 ...

  6. Hdu 5289-Assignment 贪心,ST表

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=5289 Assignment Time Limit: 4000/2000 MS (Java/Others) ...

  7. hdu 4803 贪心/思维题

    http://acm.hdu.edu.cn/showproblem.php?pid=4803 话说C++还卡精度么?  G++  AC  C++ WA 我自己的贪心策略错了 -- 就是尽量下键,然后上 ...

  8. hdu 1735(贪心) 统计字数

    戳我穿越:http://acm.hdu.edu.cn/showproblem.php?pid=1735 对于贪心,二分,枚举等基础一定要掌握的很牢,要一步一个脚印走踏实 这是道贪心的题目,要有贪心的意 ...

  9. hdu 4974 贪心

    http://acm.hdu.edu.cn/showproblem.php?pid=4974 n个人进行选秀,有一个人做裁判,每次有两人进行对决,裁判可以选择为两人打分,可以同时加上1分,或者单独为一 ...

随机推荐

  1. img,bg

    img vertical-align:middle;    设置页面垂直居中的,如果无效的话使用 display:table-cel,讲块元素转化为单元格,在使用vertical-align属性水质居 ...

  2. (转)Linux 最大进程数

    Linux 最大进程数  原文:https://www.cnblogs.com/pangguoping/p/5792075.html 前言 使用环境:centos 7系统 一.查看用户打开的最大进程数 ...

  3. mongodb慢查询记录

    在 MySQL中,慢查询日志是经常作为我们优化数据库的依据,那在MongoDB中是否有类似的功能呢?答案是肯定的,那就是Mongo Database Profiler.不仅有,而且还有一些比MySQL ...

  4. MySql存储引擎MyISAM和InnoDB的区别

    1.MySQL默认采用的是MyISAM. 2.MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速 ...

  5. openLayers3 中实现多个Overlay

    此篇的目的是为了记录下用Overlay的一些操作. 其实实现多个就是创建多个div,然后给每个div绑定Overlay. //页面加载完函数 --显示个关键点的名称 window.onload = f ...

  6. 【学习笔记】关于DOM4J:使用DOM4J解析XML文档

    一.概述 DOM4J是一个易用的.开源的库,用于XML.XPath和XSLT中.采用了Java集合框架并完全支持DOM.SAX.和JAXP. DOM4J最大的特色是使用大量的接口,主要接口都在org. ...

  7. python的if语句

    1.条件测试 (1)概念: 每条if语句的核心都是一个值为True或False的表达式,这种表达式被称为条件测试.Python 根据条件测试的值为True还是False来决定是否执行if语句中的代码. ...

  8. Etcd入门教程

    etcd是一个类似于zk的工具,用于保存值,节点-值这种映射关系的.节点组织结构类似unix文件系统结构,从/最开始.比如一个/test/name节点,值为guanxianseng.可以通过etcdc ...

  9. C# ObjectArx cad二次开发

    1 环境搭建:安装CAD 和objectArx库,这里安装的是cad2012和objectArx2010 ,vs是2010 2 新建一个类库项目,引用objectArx安装目录下inc文件夹下的AcD ...

  10. mysql六:mysql内置功能(视图、触发器、事务、存储过程、函数)

    一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 通过使用视图可以把查询过程中的 ...