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; }