Rikka with coin 思维题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6685

题意:用面额分别为10,20,50,100的四种硬币组成n(n<=100)个数(wi<=1e9),求问最少需要多少硬币

输入:
The first line of the input contains a single integer T(1T500), the number of test cases.

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

The second line contains n positive integers w1,,wn(1wi109), which represents the prices.

分析:

首先 10分的硬币多只会用一个,如果用了两个,直接替换成一个 10分一个 20分一定不亏。(两个10分表示的数是一个20一个10表示的数的子集)
20分的硬币多只会用三个,如果用了四个,直接替换成一个 10分两个20  分一个 50分一定不亏。

50分的硬币多只会用一个,如果用了两个,直接替换成一个 50分和一个1元一定不亏。

对于任何一种情况,重复使用上述规则一定会达到一个 10分硬币最多一个, 20分最多三个, 50分最多一个的情况,不会陷入重复甩锅的死循环。
因此枚举这三种硬币分别用了多少个,然后整百的部分直接用一元硬币填,取少的答案就行了。

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
const int N=1100,lim=40;
int A[N],n,ans=1e9,pd[lim+10];
const int w[4]={1,2,5,10};
const int num[4]={1,3,1,3};
void put(int k){
    for (int i=lim;i>=k;i--) pd[i]|=pd[i-k];
}
int calc(){
    int w=0;
    for (int i=1;i<=n;i++){
        int k=A[i]%10;
        int num=1e9;
        while (k<=lim&&k<=A[i]){
            if (pd[k]) num=min(num,(A[i]-k)/10);
            k+=10;
        }
        w=max(w,num);
    }
    return w;
}
void getans(int k,int tot){
    if (k==4){
        ans=min(ans,calc()+tot); return;
    }
    int back[lim+10]; memcpy(back,pd,sizeof pd);
    for (int i=0;i<=num[k];i++){
        getans(k+1,tot+i); put(w[k]);
    }
    memcpy(pd,back,sizeof back);
}
void solve(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%d",&A[i]);
    }
    for (int i=1;i<=n;i++){
        if (A[i]%10){
            printf("-1
"); return;
        }
        A[i]/=10;
    }
    ans=1e9; memset(pd,0x00,sizeof pd); pd[0]=1;
    getans(0,0);
    printf("%d
",ans);
}
int main(){
    int t; scanf("%d",&t);
    for (;t;t--) solve();
    return 0;
}
原文地址:https://www.cnblogs.com/qingjiuling/p/11381028.html