题意:给定10种面额的货币和它们的数量上限,问构造出恰好总额为P的最小张数,无解输出-1

T=2e4,p<=1e9,c[i]<=1e5

思路:From https://blog.csdn.net/snowy_smile/article/details/49592521

如果采用最傻瓜式的贪心,我们一定是使得每枚货币的面值尽可能低。
即,如果有面值更低的硬币,我们优先使用它;它用完之后,才考虑面值更大的硬币。
这种做法显然有问题。因为它不能保证我们恰好凑得硬币的总价值为m。
1,可能不够——直接-1
2,可能会溢出,这个要怎么办呢?
我们发现,我们可以算得溢出的硬币面值more。
如果我们能求出,之前选取硬币中,凑成面值总额为more的最少硬币个数,这样减一下即可得到答案?
但是这里就不能再继续傻瓜下去啦,我们可能会面临一个问题——
尽管我们之前的做法,留给了我们回退的余地,但是其依然有可能出现无法回退,错误判定为无解的状况。
比如:我们有50元硬币*1,20元硬币*3,我们想要凑得面额为50的硬币。
这种做法会先算入20元硬币*3,然后不论怎么回退都没有办法达成目的。
为什么会出现这种情况呢?
我们发现,这是因为,对于给定的所有面值,
每个面值都是比它大的所有面值的约数,除了(20<->50),(200<->500)这两个关系。
如果不存在这两个特殊关系,那么我们可以就采取一开始的贪心原则。
因为小的面值是比它大的所有面值的因子,所以大硬币所能拼凑的面额它一定能拼成。
也就是说,它不仅在数量上保证了更多,也在拼凑额度的功能上更优。
所以这时可以贪心:永远都拿面额更小的,直到面额>=m。
这里还是会出现面额可能超出的情况,但是首先超出的是大面额。而我们所有的小面额都取了。
而这时,我们操作的灵活性会是最大的,接下来的调整一定可以完成。
如果采取这个贪心做下去,那就只需要解决这两个特殊关系啦。
如何解决呢?
我们发现问题就是:
50可能取奇数次,这是20所凑不出的。
500可能取奇数次,这是200所凑不出的。
于是我们枚举以下四种情况
(50和500都是偶数个,不先取50和500)
(50为奇数个,500为偶数个,即我们先取一个50)
(50为偶数个,500为奇数个,即我们先取一个500)
(50为奇数个,500为奇数个,即我们先取一个50和一个500)
之后对于50和500都成对地取。
每次取50或500的时候就取偶数个。然而消除的时候也消除偶数个。
这样的枚举,就消除了这个两个特殊关系的影响啦。
为什么呢,我们可以分析下:
先以50为例,我们先枚举最后取50的奇偶性,再贪心从小到大取数,然后溢出了,开始考虑移除(移除最少的个数)——
不论最后取的50是奇数个还是偶数个,对于每个成对的50(即100)而言,
结合之间的"约数结论",只要我们剩余的数的总和大于等于100,那么它们是一定能够拼凑出100的。
于是我们有:这里移除2个50肯定是移除最少的个数,是最优的。
同理,对于500而言,先决定它最后的奇偶性。
然后对于每个成对的500,之前的所有数都是1000的因子。如果数值之和达到1000,便一定能凑得1000。
于是只要保证"之下的所有数的数值之和不减小到不够",这里就可以直接移除这个1000,肯定更优。

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 20
#define M 110000
#define eps 1e-8
#define pi acos(-1)
#define oo 1000000000
#define MOD 10007 const ll c[]={,,,,,,,,,,}; int a[N],b[N],d[N],n,ans; ll min(ll x,ll y)
{
if(x<y) return x;
return y;
} int isok(ll s,int p)
{
int num=;
for(int i=p;i>=;i--)
{
if(d[i]==-)
{
int t=min(b[i],s/c[i]);
num+=t;
s-=t*c[i];
}
else
{
int t=min(b[i],s/c[i]);
if(t&) t--;
num+=t;
s-=t*c[i];
}
}
if(s==) return num;
return -;
} void solve()
{
if(d[]>a[]||d[]>a[]) return;
memset(b,,sizeof(b));
int s1=d[]+d[];
ll s2=d[]*+d[]*;
for(int i=;i<=;i++)
{
if(d[i]==-)
{
s1+=a[i];
b[i]=a[i];
s2+=c[i]*a[i];
}
else
{
b[i]=a[i]-d[i];
if(b[i]&) b[i]--;
s1+=b[i];
s2+=c[i]*b[i];
}
if(s2>=n)
{
int t=isok(s2-n,i);
if(t!=-)
{
s1-=t;
ans=max(ans,s1);
}
return;
}
}
} int main()
{
//freopen("hdoj5527.in","r",stdin);
//freopen("hdoj5527.out","w",stdout);
int cas;
scanf("%d",&cas);
for(int v=;v<=cas;v++)
{
scanf("%d",&n);
for(int i=;i<=;i++) scanf("%d",&a[i]);
memset(d,-,sizeof(d));
ans=-;
d[]=; d[]=; solve();
d[]=; d[]=; solve();
d[]=; d[]=; solve();
d[]=; d[]=; solve();
printf("%d\n",ans);
}
return ;
}

【HDOJ5527】Too Rich(贪心,构造)的更多相关文章

  1. 贪心+构造 Codeforces Round #277 (Div. 2) C. Palindrome Transformation

    题目传送门 /* 贪心+构造:因为是对称的,可以全都左一半考虑,过程很简单,但是能想到就很难了 */ /************************************************ ...

  2. 贪心/构造/DP 杂题选做

    本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...

  3. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  4. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  5. Codeforces Round #301 (Div. 2)(A,【模拟】B,【贪心构造】C,【DFS】)

    A. Combination Lock time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...

  6. Codeforces 1082D Maximum Diameter Graph (贪心构造)

    <题目链接> 题目大意:给你一些点的最大度数,让你构造一张图,使得该图的直径最长,输出对应直径以及所有的边. 解题分析:一道比较暴力的构造题,首先,我们贪心的想,要使图的直径最长,肯定是尽 ...

  7. hdu 4982 贪心构造序列

    http://acm.hdu.edu.cn/showproblem.php?pid=4982 给定n和k,求一个包含k个不相同正整数的集合,要求元素之和为n,并且其中k-1的元素的和为完全平方数 枚举 ...

  8. Codeforces Round #335 (Div. 2) D. Lazy Student 贪心+构造

    题目链接: http://codeforces.com/contest/606/problem/D D. Lazy Student time limit per test2 secondsmemory ...

  9. URAL 1995 Illegal spices 贪心构造

    Illegal spices 题目连接: http://acm.timus.ru/problem.aspx?space=1&num=1995 Description Jabba: Han, m ...

  10. CROC 2016 - Elimination Round (Rated Unofficial Edition) E. Intellectual Inquiry 贪心 构造 dp

    E. Intellectual Inquiry 题目连接: http://www.codeforces.com/contest/655/problem/E Description After gett ...

随机推荐

  1. 认识/etc/passwd和/etc/shadow

    认识/etc/passwd和/etc/shadow============================== /etc/passwd [root@aminglinux ~]# head -n1 /e ...

  2. python使用PyQt5,及QtCreator,qt-unified界面设计以及逻辑实现

    1.环境安装: 1.安装pyQt5 pip3 install pyQt5   2.安装设计器 pip3 install pyQt5-tools  (英文版的) 我是用的是自己Windows上安装的qt ...

  3. django开发基础

    一.配置静态文件 https://www.cnblogs.com/lshedward/p/10351051.html 二.路由分发 https://www.cnblogs.com/lshedward/ ...

  4. 2018年湘潭大学程序设计竞赛 E 吃货

    题目描述 作为一个标准的吃货,mostshy又打算去联建商业街觅食了.混迹于商业街已久,mostshy已经知道了商业街的所有美食与其价格,而且他给每种美食都赋予了一个美味度,美味度越高表示他越喜爱这种 ...

  5. 笔记-算法-KMP算法

    笔记-算法-KMP算法 1.      KMP算法 KMP算法是一种改进的字符串匹配算法,KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一 ...

  6. Spark性能优化:shuffle调优

    调优概述 大多数Spark作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘IO.序列化.网络数据传输等操作.因此,如果要让作业的性能更上一层楼,就有必要对shuffle过程进行 ...

  7. 常用Style

    有些输入框什么的,字数限制什么的style,ceb为我们写好了.我感觉,每个app的style都是很有用的一个东西. <?xml version="1.0" encoding ...

  8. 纯javascript验证,100行超精简代码。

    这篇文章转自--寒飞,原帖地址http://blog.csdn.net/luoyehanfei/article/details/42262249 QQ交流群235032949 纯javascript验 ...

  9. 33、secret

    CemFjee9rueuoeeQhgkxCee9kee7nO+8jOW6lOeUqO+8jOaVsOaNruW6k+acjeWKoeeahOWFs+mUruS/oeaBr++8iOWmgiDmnI3l ...

  10. CMD 下运行python的unittest测试脚本无输出

    正常情况下windows的命令行执行python脚本命令: python 脚本名.py 我这样做了,看截图可以看到,并没有期待中那样有一堆高大上的信息输出,反而毛都没有!!!! 于是,我想起了度娘,但 ...