hdu多校第九场 1006 (hdu6685) Rikka with Coin 暴力

题意:

有一些1毛,2毛,5毛,1块的钢镚,还有一些价格不同的商品,现在要求你带一些钢镚,以保证这些商品中任选一件都能正好用这些钢镚付账,问最少带多少钢镚。

题解:

对于最优解,1毛的钢镚最多带1个,带两个就还不如带一个2毛的,同理2毛的最多带四个,5毛的最多带1个,一块的没有限制。

因此,预处理出1个1毛,4个2毛,1个5毛的所有子集,它们分别能组成哪些额度。

暴力枚举,并维护最少1块数量即可。

#include<iostream>
#include<set>
#include<map>
using namespace std;
set<int> money[(1<<6)+10];
int count[(1<<6)+10];
int size[(1<<6)+10];
int a[110];
inline int bit(int x,int b){
    return (x>>b)&1;
}
void init(){
    //预处理答案 
    for(int i=0;i<(1<<6);i++){
        size[i]=10*bit(i,0)+20*bit(i,1)+20*bit(i,2)+20*bit(i,3)+20*bit(i,4)+50*bit(i,5);
        count[i]=bit(i,0)+bit(i,1)+bit(i,2)+bit(i,3)+bit(i,4)+bit(i,5);
    }
    for(int i=0;i<(1<<6);i++){
        for(int j=0;j<=i;j++){
            if((i&j)==j){
                money[i].insert(size[j]);
            }
        }
    }
}
int main(){
    int t;
    init(); 
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int minn=0x3f3f3f3f;//所有钱币组合中最少耗费钱币数 
        for(int i=0;i<(1<<6);i++){
            int maxx=0;//对于同一种钱币组合,满足所有价格,所需100元张数 
            for(int j=1;j<=n;j++){
                int cc=0x3f3f3f3f; 
                //对于同一种价格,同一种钱币组合,不同的能支付的钱数,最少需要的额外100元张数 
                for(set<int>::iterator it=money[i].begin();it!=money[i].end();it++){
//                    printf("last:%d\n",a[j]-*it);
                    if((a[j]-*it)%100==0)cc=min(cc,(a[j]-*it)/100);
                }
                if(cc==0x3f3f3f3f)goto A;
                //此解无法满足需求 
                else maxx=max(maxx,cc);
            }
//            printf("100:%d other:%d\n",maxx,count[i]);
            minn=min(minn,maxx+count[i]);
            A:;
        }
        printf("%d\n",(minn==0x3f3f3f3f)?-1:minn);
    }
    return 0;
}
 

 

posted @ 2019-08-19 20:41  Isakovsky  阅读(238)  评论(0编辑  收藏  举报