对于$w$的表示方案,可以用序列描述,即$x_{i}$表示第$i$种货币的数量

贪心策略得到的方案即是(对应序列)字典序最大的方案,并定义最优策略得到的方案为在最小化货币总数的基础上,(对应序列)字典序最大的方案

记$g_{w}$和$f_{w}$分别为贪心和最优策略下$w$的表示方案,问题即求最小的$w$满足$\sum_{i=1}^{n}g_{w,i}>\sum_{i=1}^{n}f_{w,i}$

(以下方案比较均按照字典序,性质1-4均比较显然,可以简单思考后跳过证明)

性质1:$\forall w_{1}<w_{2},g_{w_{1}}<g_{w_{2}}$

反证法,若$g_{w_{1}}\ge g_{w_{2}}$,构造$g'$为在$g_{w_{1}}$的方案再选择$w_{2}-w_{1}$个$a_{n}=1$,显然$g'$也是$w_{2}$的一种表示方案且$g'>g_{w_{1}}\ge g_{w_{2}}$,与贪心策略(字典序的最大性)矛盾

性质2:记答案为$s$,则$\forall 0\le w<s,g_{w}=f_{w}$

根据最优策略和$s$的最小性,有$\forall 0\le w<s,\sum_{i=1}^{n}g_{w,i}=\sum_{i=1}^{n}f_{w,i}$,即$g_{w}$取到了货币总数的最小值,那么根据最优策略(字典序的最大性)知$g_{w}\le f_{w}$

另一方面,根据贪心策略知$g_{w}\ge f_{w}$,结合两者即得证

性质3:若$g/f_{w,i}\ne 0$,则$g/f_{w-a_{i}}$必然是$g/f_{w}$的方案再去掉一个$a_{i}$

(不妨以$g$为例,$f$可以类似证明)

构造$g'$为$g_{w}$的方案再去掉一个$a_{i}$,若$g'\ne g_{w-a_{i}}$,根据贪心策略知$g'<g_{w-a_{i}}$

再在两者的方案中同时选择一个$a_{i}$,前者显然变为$g_{w}$,又与贪心策略矛盾

性质4:$\forall 1\le i\le n$,$g_{s,i}$和$f_{s,i}$不同时非0

反证法,若存在$i$使得$g_{s,i},f_{s,i}$均非0,任取其中一个$i$

根据性质2,有$g_{s-a_{i}}=f_{s-a_{i}}$,进而$\sum_{i=1}^{n}g_{s-a_{i},i}=\sum_{i=1}^{n}f_{s-a_{i},i}$

又根据性质3,有$\sum_{i=1}^{n}g/f_{s-a_{i},i}=\sum_{i=1}^{n}g/f_{s,i}-1$

其中左式两者相等,而右式两者不等(根据$s$的定义),矛盾

令$x$和$y$分别为$f_{s}$第一个和最后一个非0的位置(显然存在),则有以下性质——

性质5:$x\ge 2,s\ge a_{x-1}$且$s-a_{y}<a_{x-1}$

关于前者(指$x\ge 2,s\ge a_{x-1}$),若不满足显然$g_{s,x}\ne 0$,与性质4矛盾

关于后者,根据性质2,有$f_{s-a_{y}}=g_{s-a_{y}}$,而前者是$f_{s}$的方案中再去掉一个$a_{y}$,那么$1,2,...,x-1$也均为0,而如果$s-a_{y}\ge a_{x-1}$显然后者$1,2,...,x-1$中存在非0位,矛盾

结论:$\forall x\le i<y,f_{s,i}=g_{a_{x-1}-1,i}$且$f_{s,y}=g_{a_{x-1}-1,y}+1$

根据性质1和2,有$f_{s-a_{x}}=g_{s-a_{x}}>g_{a_{x-1}-1-a_{x}}$

根据性质3,两者分别是$f_{s}$和$g_{a_{x-1}-1}$的方案再去掉一个$a_{x}$(注意$a_{x-1}-1\ge a_{x}$),进而在两者的方案中同时选择一个$a_{x}$,即得到$f_{s}>g_{a_{x-1}-1}$

另一方面,同样根据性质1和2,有$f_{s-a_{y}}=g_{s-a_{y}}\le g_{a_{x-1}-1}<f_{s}$

同样根据性质3,$f_{s-a_{y}}$是$f_{s}$的方案中再去掉一个$a_{y}$,而字典序因此变化,显然结论成立

根据此结论,显然$f_{w}$被$x,y$唯一确定(其余位置均为0),枚举$x,y$并求出$f_{w}$,进而求出$w$和$g_{w}$并比较两者的货币数即可(注意这里并不保证求出的$f_{w}$是最优的,但在答案处是最优的,且比答案小的最优方案都不比$g_{w}$优,该方案显然也不能比$g_{w}$优)

贪心策略的方案容易$o(n)$求出,总复杂度为$o(n^{3})$,可以通过

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 405
4 int n,ans,a[N],f[N];
5 void check(){
6 int cnt=0,sum=0;
7 for(int i=1;i<=n;i++)cnt+=f[i],sum+=f[i]*a[i];
8 for(int i=1,s=sum;i<=n;i++)cnt-=s/a[i],s%=a[i];
9 if (cnt<0)ans=min(ans,sum);
10 }
11 int main(){
12 scanf("%d",&n);
13 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
14 ans=2e9;
15 for(int i=1;i<=n;i++){
16 memset(f,0,sizeof(f));
17 for(int j=i,s=a[i-1]-1;j<=n;j++){
18 f[j]=s/a[j],s%=a[j];
19 f[j]++,check(),f[j]--;
20 }
21 }
22 if (ans==2e9)ans=-1;
23 printf("%d\n",ans);
24 return 0;
25 }

[cf10E]Greedy Change的更多相关文章

  1. Greedy Change

    Greedy Change time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  2. [Codeforces 10E] Greedy Change

    Brief Introduction: 给你一些种类的硬币,用最少的硬币数表示X 求最小的使贪心算法错误的X Algorithm: 一道论文题,<A Polynomial-time Algori ...

  3. 贪婪算法(Greedy Algorithm)

    Greedy Algorithm <数据结构与算法--C语言描述> 图论涉及的三个贪婪算法 Dijkstra 算法 Prim 算法 Kruskal 算法 Greedy 经典问题:coin ...

  4. 算法与数据结构基础 - 贪心(Greedy)

    贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...

  5. “知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 贪心算法(greedy)

    --> 贪心算法 1)题解 •        分别用V0.V1和V>=2表示度为0.1以及至少为2的顶点集合 •        对于每个顶点,维护三个属性: •        degree ...

  6. 【LeetCode】贪心 greedy(共38题)

    [44]Wildcard Matching [45]Jump Game II (2018年11月28日,算法群衍生题) 题目背景和 55 一样的,问我能到达最后一个index的话,最少走几步. 题解: ...

  7. 代码的坏味道(10)——发散式变化(Divergent Change)

    坏味道--发散式变化(Divergent Change) 发散式变化(Divergent Change) 类似于 霰弹式修改(Shotgun Surgery) ,但实际上完全不同.发散式变化(Dive ...

  8. USACO . Greedy Gift Givers

    Greedy Gift Givers A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided to exchange gifts ...

  9. [LeetCode] Coin Change 硬币找零

    You are given coins of different denominations and a total amount of money amount. Write a function ...

随机推荐

  1. nodejs 安装 报错解决方案

    win10安装nodejs之后,查看版本号在终端输入node -v成功输出版本号,输入npm -v 之后报错...... 反复安装卸载之后,有点奔溃,最后的解决方案是:手动删除"C:\Use ...

  2. Java秘诀!Java关系运算符介绍

    运算符丰富是 Java 语言的主要特点之一,它提供的运算符数量之多,在高级语言中是少见的. Java 语言中的运算符除了具有优先级之外,还有结合性的特点.当一个表达式中出现多种运算符时,执行的先后顺序 ...

  3. Schematics Tools(Schematics 工具)

    Schematics工具 # Process: 创建逻辑示意图 arcpy.CreateDiagram_schematics("", "", "&qu ...

  4. Java基础之(一):JDK的安装以及Notepad++的下载

    从今天开始就开始我的Java的学习了,学习Java前需要做一些前期的准备工作.好了,现在我们先一起来安装JDK. JDK的安装 JDK下载链接:JDK 下载电脑对应的版本,同意协议 双击安装JDK 将 ...

  5. CF193D Two Segments (线段树+dp)(外加两个扩展题)

    大概算是个系列整理 (最强版是模拟赛原题)) 首先,我们先来看这个题目. QWQ一开始是毫无头绪,除了枚举就是枚举 首先,我们可以枚举一个右端点,然后算一下当前右端点的答案 我们令\(f[l,r]\) ...

  6. xshell连接vmware系统完整版

    设置静态ip需要修改文件一共有两个要修改的文件vi /etc/resolv.confvi /etc/sysconfig/network-scripts/ifcfg-eno16777736 第一个文件 ...

  7. python中的 * 和 ** 作用含义

    python中的 * 和 ** ,能够让函数支持任意数量的参数,它们在函数定义和调用中,有着不同的目的 一. 打包参数 * 的作用:在函数定义中,收集所有位置参数到一个新的元组,并将整个元组赋值给变量 ...

  8. Billu_b0x内网渗透-vulnhub

    个人博客:点我 本次来试玩一下vulnhub上的Billu_b0x,只有一个flag,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶场 ...

  9. Python小工具:据说这是搜索文件最快的工具!没有之一!一起感受下......

    电脑自带的搜索文件功能相信大家都体验过,那是真的慢,等它找到文件,我都打完一把游戏了! 那必须不能忍,于是我自己做了一个文件搜索工具,犄角旮旯的文件都能一秒钟搜索出来的那种! 保证能把你们男(女)朋友 ...

  10. 运维常用python库&模块

    sutil:是一个跨平台库(https://github.com/giampaolo/psutil)能够实现获取系统运行的进程和系统利用率(内存,CPU,磁盘,网络等),主要用于系统监控,分析和系统资 ...