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. Spark遇到的报错和坑

    1. Java版本不一致,导致启动报错. # 解决方法: 在启动脚本最前边添加系统参数,指定Java版本 export JAVA_HOME=/usr/java/jdk1..0_181-amd64/jr ...

  2. css 小知识点

    苹果浏览默认表单 单选 多选 下拉列表 效果的去除 提交按钮-webkit-appearance: none;-moz-appearance: none;-ms-appearance: none;ap ...

  3. CSAPP阅读笔记-32位64位的区别--来自第三章引言的笔记--P110

    仅从寻址上看,32位和64位机器能寻址的内存空间大小不同. 需要知道的是,计算机系统对存储器作了抽象,程序“认为”内存是一个很大的字节数组,然而实际上它是由多个硬件存储器和操作系统组合起来实现的. 程 ...

  4. python 爬虫系列08-同步斗图一波

    一波大图来袭 import requests from lxml import etree from urllib import request import os import re def par ...

  5. PHP 设置 socket连接

    摘要: 作者博文地址:https://www.cnblogs.com/liu-shuai/ nginx和fastcgi的通信方式有两种,一种是TCP的方式,一种是unix socket方式. sock ...

  6. lua "诡异"的return用法

    https://yq.aliyun.com/articles/11387 lua "诡异"的return用法   德哥 2016-03-29 15:38:42 浏览5690 评论0 ...

  7. [實現DDD] 第11章 工廠

    創建過程中須考慮一些重要細節, 否則所創建的聚合將處於不正確的狀態, 使用適當的工廠方法可以確保這一點, 而客戶端只需輸入基本的參數(通常是值對象), 另外, 工廠能更好地表達出通用語言, 使團隊成員 ...

  8. [转]Newtonsoft.Json高级用法

    本文转自:http://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多 ...

  9. ES6 克隆对象

    浅克隆:只能克隆原始对象自身的值,不能克隆它继承的值 方法一: function clone(origin) { return Object.assign({}, origin); } 方法二: fu ...

  10. 一分钟学会Git操作流程

    今天整理下公司操作git 流程,尽量用最最简洁的方式整理出来,方便以后有新来的同事学习使用. 我整理的这个Git操作,基本上只需要一分钟,就可以轻松上手啦!!! 一. 拉取提交操作 1.拉取远程代码 ...