Canonical Coin Systems

题目描述

A coin system S is a finite (nonempty) set of distinct positive integers corresponding to coin values, also called denominations, in a real or imagined monetary system. For example, the coin system in common use in Canada is {1, 5, 10, 25, 100, 200}, where 1 corresponds to a 1-cent coin and 200 corresponds to a 200-cent (2-dollar) coin. For any coin system S, we assume that there is an unlimited supply of coins of each denomination, and we also assume that S contains 1,since this guarantees that any positive integer can be written as a sum of (possibly repeated) values in S.

Cashiers all over the world face (and solve) the following problem: For a given coin system and a positive integer amount owed to a customer, what is the smallest number of coins required to dispense exactly that amount? For example, suppose a cashier in Canada owes a customer 83 cents. One possible solution is 25+25+10+10+10+1+1+1, i.e.,8 coins, but this is not optimal, since the cashier could instead dispense 25 + 25 + 25 + 5 + 1 + 1 + 1, i.e., 7 coins (which is optimal in this case). Fortunately, the Canadian coin system has the nice property that the greedy algorithm always yields an optimal solution, as do the coin systems used in most countries. The greedy algorithm involves repeatedly choosing a coin of the

largest denomination that is less than or equal to the amount still owed, until the amount owed reaches zero. A coin system for which the greedy algorithm is always optimal is called canonical.

Your challenge is this: Given a coin system S = {c1, c2, . . . , cn }, determine whether S is canonical or non-canonical. Note that if S is non-canonical then there exists at least one counterexample, i.e., a positive integer x such that the minimum number of coins required to dispense exactly x is less than the number of coins used by the greedy algorithm. An example of a non-canonical coin system is {1, 3, 4}, for which 6 is a counterexample, since the greedy algorithm yields 4 + 1 + 1 (3 coins), but an optimal solution is 3 + 3 (2 coins). A useful fact (due to Dexter Kozen and Shmuel Zaks) is that if S is non-canonical, then the smallest counterexample is less than the sum of the two largest denominations.

输入

Input consists of a single case. The first line contains an integer n (2 ≤ n ≤ 100), the number of denominations in the coin system. The next line contains the n denominations as space-separated integers c1 c2 . . . cn, where c1 = 1 and c1 < c2 < . . . < cn ≤ 106.

输出

Output “canonical” if the coin system is canonical, or “non-canonical” if the coin system is non-canonical.

样例输入

4
1 2 4 8

样例输出

canonical

题意

有n种面额的货币,如果能保证所以金额,用贪心思想算出的货币张数(每次减先大面额的货币)和 正确的货币张数是相同的,就是规范的(输出canonical),如果贪心算出的货币张数比正确算出的多,那就是不规范的(输出non-canonical)

题解

正确的货币张数可以通过完全背包算出 转移方程 dp[i] = d[i - a[j] ] + 1;(dp[i]代表剩余金额为i时已经拥有的张数,a[j]代表第j张钱的面额)

代码

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define rep(i,a,n) for(int i=a;i<n;++i)
#define readc(x) scanf("%c",&x)
#define read(x) scanf("%d",&x)
#define sca(x) scanf("%d",&x)
#define read2(x,y) scanf("%d%d",&x,&y)
#define read3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define print(x) printf("%d\n",x)
#define mst(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&-x
#define lson(x) x<<1
#define rson(x) x<<1|1
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<ll,ll> P;
const int INF =0x3f3f3f3f;
const int inf =0x3f3f3f3f;
const int mod = 1e9+7;
const int MAXN = 105;
const int maxn =2000010;
using namespace std;
int n;
int a[maxn],dp[maxn];
int main(){
sca(n);
for(int i = 0; i < n; i++)
sca(a[i]);
sort(a,a+n);
int maxl = a[n - 1] * 2;
for(int i = 0; i < maxl; i++) dp[i] = INF;
dp[0] = 0;
int flag = 1;
for(int i = 1; i < maxl; i++){
for(int j = 0; j < n; j++){
if(a[j] <= i)
dp[i] = min(dp[i], dp[i - a[j]] + 1); //背包
}
int cnt = 0;
int sum = i;
int pos = n - 1;
while(sum){ //贪心
while(sum >= a[pos]){
sum -= a[pos];
cnt ++;
}
pos--;
}
if(cnt > dp[i]) flag = 0; //不等就是不规范
}
if(flag) printf("canonical\n");
else printf("non-canonical\n");
return 0;
}

最新文章

  1. 老贼博客php教程从零学习PHP开始写作,顺祝新同事快乐!
  2. js⑥
  3. sql 查询执行的详细时间profile
  4. css3 javascript 实现菜单按钮特效
  5. Ubuntu 安装 Sun JDK
  6. socket设置为非阻塞方式(windows和linux)
  7. CSS-id选择器-类选择器-属性选择器
  8. 重构oceanbase的一个函数
  9. RHEL 7.0 修改防火墙配置
  10. 【Cloud Foundry】Could Foundry学习(二)——核心组件分析
  11. reduceByKeyLocally
  12. tp备份数据
  13. OpenCV入门之寻找图像的凸包(convex hull)
  14. zxing二维码的生成与解码(C#)
  15. golang channle close() x,ok := &lt;- c
  16. ajax大并发问题
  17. 8.2 DRAM和SRAM
  18. unity中鼠标按下加速漫游,鼠标抬起减速漫游。
  19. TCP/IP协议分层详解
  20. Python之路(第八篇)Python内置函数、zip()、max()、min()

热门文章

  1. python改变导入模块中的变量的问题
  2. urllib库爬取实例
  3. ssh 免密码登录实现批量处理
  4. leetcode.双指针.680验证回文字符串-Java
  5. WEBRTC三种类型(Mesh、MCU 和 SFU)的多方通信架构
  6. 从一个Activity打开另外一个Activity
  7. C中printf函数的用法总结
  8. 【知识强化】第四章 网络层 4.3 IP
  9. 2019-8-31-C#-使用汇编
  10. mongoose 与 mylab 的使用 (1)