Oliver分别有币值为1,3,5,7,9,13元的硬币a,b,c,d,e,f枚。一天她去大学生超市买糖吃,糖的价格为g元。
问:用Oliver仅有的这6种硬币去恰好购买这g元的糖果,最少需要支付多少个硬币?(当不能支付时输出“impossible”)
输入
输入数据有多组(当输入连续的7个零时,结束。该组数据不做处理)
每组数据依次输入币值为1,3,5,7,9,13元的硬币的个数,以及糖果的价格g(小于5000)。
输出
输出数据有多组,每组数据一行,为需要支付的最少硬币个数。
样例输入
样例输出
解题思路:多重背包
1 #include <bits/stdc++.h> 2 using namespace std; 3 int val[7]={0,1,3,5,7,9,13}; 4 int arr[7],number; 5 const int INF=0x3f3f3f3f; 6 struct Node{ 7 int v,w; 8 }; 9 vector<Node> vec; 10 int main() 11 { 12 while(scanf("%d",&arr[1])){ 13 for(int i=2;i<=6;i++){ 14 scanf("%d",&arr[i]); 15 } 16 scanf("%d",&number); 17 if(arr[1]==0&&arr[2]==0&&arr[3]==0&&arr[4]==0&&arr[5]==0&&arr[6]==0&&number==0){ 18 break; 19 } 20 int dp[5005]; 21 for(int i=1;i<=number;i++){ 22 dp[i]=INF; 23 } //dp[0]=0;34 24 for(int i=1;i<=6;i++){ //二进制优化 全部情况都考虑到了 25 for(int k=1;k<=arr[i];k*=2){ 26 arr[i]-=k; 27 vec.push_back({k*val[i],k}); 28 } 29 if(arr[i]>0){ 30 vec.push_back({arr[i]*val[i],arr[i]}); 31 } 32 } 33 for(auto X:vec){ 34 for(int j=number;j>=X.v;j--){ 35 dp[j]=min(dp[j],dp[j-X.v]+X.w); 36 } 37 } 38 if(dp[number]==INF) 39 printf("impossible "); 40 else 41 printf("%d ",dp[number]); 42 vec.clear(); 43 } 44 return 0; 45 }