4702: 分糖果系列一

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\n");
40         else
41             printf("%d\n",dp[number]);
42         vec.clear();
43     }
44     return 0;
45 }
View Code

 

posted @ 2019-05-14 21:23  厂长在线养猪  Views(165)  Comments(0Edit  收藏  举报