CF10E Greedy Change 判断硬币系统是否能用贪心策略

Billy investigates the question of applying greedy algorithm to different spheres of life. At the moment he is studying the application of greedy algorithm to the problem about change. There is an amount of n coins of different face values, and the coins of each value are not limited in number. The task is to collect the sum x with the minimum amount of coins. Greedy algorithm with each its step takes the coin of the highest face value, not exceeding x. Obviously, if among the coins‘ face values exists the face value 1, any sum x can be collected with the help of greedy algorithm. However, greedy algorithm does not always give the optimal representation of the sum, i.e. the representation with the minimum amount of coins. For example, if there are face values {1, 3, 4} and it is asked to collect the sum 6, greedy algorithm will represent the sum as 4 + 1 + 1, while the optimal representation is 3 + 3, containing one coin less. By the given set of face values find out if there exist such a sum x that greedy algorithm will collect in a non-optimal way. If such a sum exists, find out the smallest of these sums.

Input

The first line contains an integer n (1 ≤ n ≤ 400) — the amount of the coins‘ face values. The second line contains n integers ai (1 ≤ ai ≤ 109), describing the face values. It is guaranteed that a1 > a2 > ... > an and an = 1.

Output

If greedy algorithm collects any sum in an optimal way, output -1. Otherwise output the smallest sum that greedy algorithm collects in a non-optimal way.

Sample test(s)

input

525 10 5 2 1

output

-1

input

34 3 1

output

6

参考论文《A polynomial-time algorithm for the change-making problem》

设找零钱的最小表示为M(x),贪心表示为G(x),最小不满足M(x)=G(x)的值为w。

如题中input2,M(6)={0,2,0}, G(6)={1,0,2}。

设M(w)第一个非0元素在位置i,最后一个非0元素在位置j

有这么一个结论:

M(w)和G(c[i-1]-1)从1到j-1位都相等,M[j]=G[j]+1。

于是可以通过枚举i,j求出w的值。

 1 #include <map>
 2 #include <set>
 3 #include <cmath>
 4 #include <queue>
 5 #include <stack>
 6 #include <cstdio>
 7 #include <string>
 8 #include <vector>
 9 #include <cstring>
10 #include <iostream>
11 #include <algorithm>
12 #define ll long long
13 #define pii pair<int, int>
14 #define mp(x,y) make_pair(x,y)
15 using namespace std;
16 const int inf = 0x7fffffff;
17 const double eps = 1e-12;
18 const int mod = 1e9+7;
19 const int maxn = 300005;
20 using namespace std;
21 int c[401];
22 int main() {
23     int n;
24     cin>>n;
25     for (int i=0; i<n; i++)
26         cin>>c[i];
27     int ans=-1;
28     for (int i=1; i<n; i++) {
29         for (int j=i; j<n; j++) {
30             //calculate G(c[i-1]-1) and w
31             int p=c[i-1]-1, cnt=1, w=c[j];
32             for (int k=i; k<=j; k++) {
33                 cnt+=p/c[k];
34                 w+=p/c[k]*c[k];
35                 p%=c[k];
36             }
37             p=w;
38             //judge whether M(w)<G(w)
39             for (int k=0; k<n; k++) {
40                 cnt-=p/c[k];
41                 p%=c[k];
42             }
43             if (cnt<0&&(ans==-1||w<ans))
44                 ans=w;
45         }
46     }
47     cout << ans << endl;
48     return 0;
49 }

CF10E Greedy Change 判断硬币系统是否能用贪心策略

时间: 2024-10-28 08:35:59

CF10E Greedy Change 判断硬币系统是否能用贪心策略的相关文章

判断目前系统中的等待事件

判断目前系统中的等待事件: SELECT SUBSTR(s1.username,1,12) "WAITING USER" , SUBSTR(s1.osuser,1,8) "OS User" , SUBSTR(TO_CHAR(w.session_id),1,5) "Sid" , p1.spid "PID" , SUBSTR(s2.username,1,12) "HOLDING User" , SUBSTR(s

Android判断当前系统时间是否在指定时间的范围内(免消息打扰)

/** * 判断当前系统时间是否在指定时间的范围内 * * @param beginHour * 开始小时,例如22 * @param beginMin * 开始小时的分钟数,例如30 * @param endHour * 结束小时,例如 8 * @param endMin * 结束小时的分钟数,例如0 * @return true表示在范围内,否则false */ public static boolean isCurrentInTimeScope(int beginHour, int beg

获取手机中所有已安装的应用,并判断是否系统应用

//获取手机中所有已安装的应用,并判断是否系统应用 ArrayList<AppInfo> appList = new ArrayList<AppInfo>(); //用来存储获取的应用信息数据,手机上安装的应用数据都存在appList里 List<PackageInfo> packages = getPackageManager().getInstalledPackages(0);   for(int i = 0; i < packages.size(); i++

Android开发实用技巧:判断当前系统语言版本

Locale locale = getResources().getConfiguration().locale; String language = locale.getLanguage(); 以上代码可以获取到当前系统的语言码,中文的语言码为ch,英文的语言码为en,完整的语言码如下: bn_BD孟加拉语(孟加拉)  bo_CN 博多语(中国)  bo_IN 博多语(印度)  ce_PH 塞布安诺语(菲律宾)  de_LI 德语(列支敦士登)  fa_AF 波斯语(阿富汗)  fa_IR 波

[黑科技] 使用Word和Excel自制题库自判断答题系统

这篇文章是LZY老师告诉我的一个方法,如果你需要做题库,并且喜欢电子答题的方法,这篇文章或许会对你有所帮助.反正李老师班级的平均成绩高出其他班级的14分,这就是它的好处,希望这篇文章对我今后的学生有所帮助吧!        注意:这篇文章涉及到Word特殊字符.通配符.Excel设置等常见问题.如果文章存在不足或错误的地方,还请海涵~        运行结果如下图所示,正确答案第一列,模拟做题的时候学生将它藏着,然后在E列进行答题,D列是在线判断系统,反复训练从而提升学生的考试分数.哈哈~哎,确

VC++ 判断当前系统为32位还是64位

尝试了在VC++环境下判断系统为32位还是64位的方法,亲测有效!提供的函数如下 BOOL IsWow64() { typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process; BOOL bIsWow64 = FALSE; fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle

leetcode 518. Coin Change 2/硬币找零 2

归纳于http://www.cnblogs.com/grandyang/p/7669088.html 原题https://leetcode.com/problems/coin-change-2/description/ 518. Coin Change 2(Medium) You are given coins of different denominations and a total amount of money. Write a function to compute the numbe

原生JS判断手机系统

点击图片,判断手机操作系统,根据手机系统跳转不同链接. function imgHref(){ var userAgent = navigator.userAgent; var isAndroid = userAgent.indexOf('Android') > -1 || userAgent.indexOf('Adr') > -1; //android终端 var isiOS = !!userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //io

js判断手机系统是iOS还是android

var isAndroid = u.indexOf('Android') > -1|| u.indexOf('Linux') > -1; //android终端或者uc浏览器 var isiOS = !!u.match(/\(i[^;]+;( U;)?CPU.+Mac OS X/);//ios终端 if (isAndroid) {//安卓端加载页面时调用 $(".main").css("height", window.screen.height -$(&