【ACM】2019杭电多校第九场1006 HDU 6685 Rikka with Coin 暴力

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=6685

Rikka with Coin

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 338    Accepted Submission(s): 71


 

Problem Description

Rikka hates coins, and she used to never carry any coins with her. These days, Rikka is doing her summer internship abroad. Without mobile payment, Rikka has to face strange prices of commodities, and as a result of always using paper currency, she has to face mountainous coins on here table.

In the local currency system, there are 4 kinds of coins: 10 cents, 20 cents, 50 cents and 1 dollar. Up to now, Rikka has gained at least 10100 coins for each kind. 

Now, Rikka is going to have dinner in the canteen, and she decides to pay the bill only with coins. There are n different combos in the canteen and the price of the ith is wi cents. Rikka would like to choose one combo as dinner but she has not decided to choose which one yet. Therefore, she wants to take some coins so that whichever she chooses, she can always pay the bill without receiving any change.

Since Rikka hates coins, she wants to carry as few coins as possible with her. As it is generally known that Rikka is not good at math, she wants you to help her make the decision.

Input

The first line of the input contains a single integer T(1≤T≤500), the number of test cases.

For each test case, the first line contains a single integer n(1≤n≤100), the number of combos sold in the canteen.

The second line contains n positive integers w1,…,wn(1≤wi≤109), which represents the prices.

Output

For each test case, output a single line with a single integer which represents the minimum number of coins. If there is no valid solution, output −1.

Hint

In the first test case, one optimal solution is to bring one coin of 10 cents and two coins of 20 cents.

In the second test case, one optimal solution is to bring 5 coins of one dollar.

Sample Input

3

5

10 20 30 40 50

5

100 200 300 400 500

1

1

Sample Output

3

5

-1

Source

2019 Multi-University Training Contest 9

题目大意:

有n个物品,拿面值分别为10块,20块,50块,100块的硬币去购买它们,问最少需要多少个硬币,使得任意买一件物品都不会有找零。

思路:

看到物品数量才100,立马想到分类讨论,写着写着发现50=20+20+10,100=50+20+20+10,把这两个算上之后,

队友芳姨又出了一组这样的数据:

5

20 40 60 50 110

分类讨论求出来是100+10+20+20+50(5),实际上应该是50+20+20+20(4)

就爆炸了啊。。。

“唉,打个表看看吧”,然后就开始打表了,但是判断条件没有想清楚,所以比赛中还是没AC。

实际上,50最多出现一次,20最多出现3次,10最多出现1次,打个表枚举一下每一种情况可以组成200以内的哪些数。

遍历数组,个位上不为0输出-1。判断十位上的数字,如果当前数字大于等于100,且十位是0或者1,就多判断此时能不能组成100或110,可以的话,面值为100的硬币数-1,取所有情况的最小值即可。

上代码(+测试数据):

#include <bits/stdc++.h>
using namespace std;
long long a[105];
int li[50][21]= //0-4
{
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//0
    {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//10
    {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//20
    {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//50
    {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},//100
    //5-11
    {0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//10+20
    {0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//20+20
    {0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},//10+50
    {0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0},//20+50
    {0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0},//10+100
    {0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0},//20+100
    {0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0},//50+100
    //12-19
    {0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//10+20+20
    {0,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},//10+20+50
    {0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},//20+20+20
    {0,0,1,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0},//20+20+50
    {0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0},//10+20+100
    {0,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0},//20+20+100
    {0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0},//10+50+100
    {0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0},//20+50+100
    //20-26
    {0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},//10+20+20+20
    {0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},//10+20+20+50
    {0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0},//20+20+20+20
    {0,0,1,0,1,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0},//20+20+20+50
    {0,1,0,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0},//10+20+20+100
    {0,1,0,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0},//10+20+50+100
    {0,0,1,0,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1},//20+20+50+100
    //27
    {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}//10+20+20+50+100
};
int main()
{
    //freopen("in.txt","r",stdin);
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        long long ans=0x3f3f3f3f,num=0;
        for(int i=0; i<n; i++)
        {
            scanf("%lld",&a[i]);
            if(a[i]%10!=0)
            {
                ans=-1;
                a[i]=a[i]-a[i]%10;
            }
        }
        if(ans==-1)
        {
            printf("-1\n");
            continue;
        }
        for(int i=0; i<=27; i++)
        {
            for(int j=0; j<n; j++)
            {
                int shi=a[j]%100/10;
                //printf("*%d\n",shi);
                if(shi==0)
                {
                    if(li[i][10])
                        num=max(num,a[j]/100-1);
                    else
                        num=max(num,a[j]/100);
                }
                else if(shi==1)
                {
                    if(a[j]>100)
                    {
                        if(li[i][1])
                            num=max(num,a[j]/100);
                        else if(li[i][11])
                            num=max(num,a[j]/100-1);
                        else
                            num=-1;
                    }
                    else
                    {
                        if(li[i][1])
                            num=max(num,a[j]/100);
                        else
                            num=-1;
                    }
                }
                else
                {
                    if(li[i][shi])
                        num=max(num,a[j]/100);
                    else
                        num=-1;
                }
                if(num==-1)
                    break;
            }
            if(num!=-1)
            {
                //printf("*%d %d\n",i,num);
                if(i==0)
                    ans=min(num,ans);
                else if(i>0&&i<=4)
                    ans=min((num+1),ans);
                else if(i>4&&i<=11)
                    ans=min((num+2),ans);
                else if(i>11&&i<=19)
                    ans=min((num+3),ans);
                else if(i>19&&i<=26)
                    ans=min((num+4),ans);
                else ans=min((num+5),ans);
            }
            num=0;
        }
        printf("%lld\n",ans);
    }
    return 0;
}
/*14
3
10 50 60
3
30 50 70
5
20 40 60 50 110
6
10 20 30 40 50 60
5
10 20 30 40 50
5
100 200 300 400 500
1
1
3
20 90 210
3
20 90 110
3
220 190 310
7
10 20 30 40 50 60 110
3
50 70 100
10
100 210 320 430 540 650 760 870 980 1090
11
100 210 320 430 540 650 760 870 980 1090 1200*/

/*
2
3
4
4
3
5
-1
5
4
6
5
3
14
15
*/

猜你喜欢

转载自blog.csdn.net/qq_41279172/article/details/99755757