问题 C: Canonical Coin Systems

问题 C: 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 ≤ 10^6

输出

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

 

样例输入

复制样例数据

4
1 2 4 8

样例输出

canonical

题意就是凑一个钱数,每次选用<=这个钱数里最大的数凑成的这个数,所用的钱的个数是否是最少的

比赛时应该是脑子短路了,以前做凑钱数的题不是贪心就是dp,这次其实就是把贪心和dp联系起来,看贪心出来的数是不是正确的最小的,也就是贪心算出来的数是不是dp算出来的数。

 

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=2e6+5;
int a[maxn];
int dp[maxn];
int getmax[maxn];
int n;

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    memset(dp,INF,sizeof dp);
    dp[0]=0;
    for(int i=1;i<=n;i++)// 完全背包求钱的数目
    {
        for(int j=0;j<=maxn;j++)
        {
            if (j>=a[i])
                dp[j]=min(dp[j],dp[j-a[i]]+1);
        }
    }

    for(int i=0;i<=maxn;i++)//贪心求钱的数目
    {
        for(int j=1;j<=n;j++)
        {
            if(i>=a[j])
                getmax[i]=getmax[i-a[j]]+1;
        }
    }

    bool flag=true;
    for(int i=0;i<maxn;i++)
    {
        if(getmax[i]!=dp[i])//两种不相同,贪心出来的不是最少的
        {
            flag=false;
            break;
        }
    }

    if(flag)
        printf("canonical\n");
    else
        printf("non-canonical\n");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值