题意:问四种价值硬币是否能凑够某个值,并输出用最少硬币的。(硬币有个数限制)
题解:多重背包,先将要凑成的小数化为整形即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[700]; 6 int pr[700]; 7 int main() 8 { 9 int a,b[5],c[5]={25,10,5,1},op[50]; 10 char s[100]; 11 op[25]=0;op[10]=1;op[5]=2;op[1]=3; 12 while(scanf(" %s %d %d %d %d",s,&b[0],&b[1],&b[2],&b[3])!=EOF) 13 { 14 memset(dp,-1,sizeof(dp)); 15 dp[0]=0; 16 bool flag=false; 17 int pos; 18 for(int i=0;s[i]!='\0';i++) 19 if(s[i]=='.') 20 { 21 pos=i; 22 flag=true; 23 break; 24 } 25 if(flag) 26 { 27 int x,y; 28 sscanf(s,"%d.%d",&x,&y); 29 if(y<10&&s[pos+1]!='0') 30 y*=10; 31 a=x*100+y; 32 } 33 else 34 sscanf(s,"%d",&a); 35 for(int i=0;i<4;i++) 36 { 37 int v=c[i],n=b[i]; 38 if(n*v>=a) 39 for(int i=0;i+v<=a;i++) 40 { 41 if(dp[i]!=-1&&(dp[i+v]==-1||dp[i+v]>dp[i]+1)) 42 dp[i+v]=dp[i]+1,pr[i+v]=i; 43 } 44 else 45 { 46 while(n--) 47 for(int i=a;i-v>=0;i--) 48 if(dp[i-v]!=-1&&(dp[i]==-1||dp[i]>dp[i-v]+1)) 49 dp[i]=dp[i-v]+1,pr[i]=i-v; 50 } 51 } 52 if(dp[a]==-1) 53 puts("NO EXACT CHANGE"); 54 else 55 { 56 int tot[4]; 57 memset(tot,0,sizeof(tot)); 58 for(int i=a;i!=0;tot[op[i-pr[i]]]++,i=pr[i]); 59 printf("%d %d %d %d\n",tot[0],tot[1],tot[2],tot[3]); 60 } 61 } 62 return 0; 63 }