hdu 1114 Piggy-Bank

题意:

已知若干种硬币的面值和重量,以及一堆硬币的总重量。

求出可以凑出这堆硬币的最小钱数或者说明不可能。

思路:

完全背包。

定义dp[i][j]表示凑到第i枚硬币,重量为j时可以凑出的最小钱数。

当dp[j+w[i]] == -1时,表示这个状态还没有到过,那么当dp[j] != -1时,才能够转移到这个状态,即dp[j+w[i]] = dp[j] + p[j];

当dp[j+w[i]] != -1并且dp[j] != -1时,dp[j+w[i]] = min(dp[j]+p[i],dp[j+w[i]])。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 505;
 7 const int M = N * 10000;
 8 
 9 int p[N],w[N];
10 
11 int dp[M];
12 
13 int main()
14 {
15     int t;
16     
17     scanf("%d",&t);
18     
19     while (t--)
20     {
21         memset(dp,-1,sizeof(dp));
22         
23         int e,f;
24         
25         scanf("%d%d",&e,&f);
26         
27         int sum = f - e;
28         
29         int n;
30         
31         scanf("%d",&n);
32         
33         for (int i = 0;i < n;i++)
34         {
35             scanf("%d%d",&p[i],&w[i]);
36         }
37         
38         dp[0] = 0;
39         
40         for (int i = 0;i < n;i++)
41         {
42             for (int j = 0;j + w[i] <= sum;j++)
43             {
44                 if (dp[j+w[i]] == -1 && dp[j] != -1)
45                 {
46                     dp[j+w[i]] = p[i] + dp[j];
47                 }
48                 else if (dp[j+w[i]] != -1 && dp[j] != -1)
49                 {
50                     dp[j+w[i]] = min(dp[j+w[i]],dp[j] + p[i]);
51                 }
52             }
53         }
54         
55         if (dp[sum] == -1) printf("This is impossible.
");
56         else printf("The minimum amount of money in the piggy-bank is %d.
",dp[sum]);
57     }
58     
59     return 0;
60 }
原文地址:https://www.cnblogs.com/kickit/p/8808778.html