码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 242 邮票和信封(完全背包)

时间:2017-02-08 22:46:31      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:eof   over   return   number   背包   ...   思路   style   uva   

https://vjudge.net/problem/UVA-242

题意:

输入s(每个信封能粘贴的最多邮票数量)和若干邮票组合,选出最大连续邮资最大的一个组合(最大连续邮资也就是用s张以内的邮票来凑1,2,3,4...n,如果无法凑成n+1,那么最大值也就是n了)。如果有多个最大值,则优先考虑邮票数少的,其次考虑邮票面值最大的那个更小的。

 

思路:

完全背包问题。

完全背包是物品无限,在这里和题意相符合,每种邮票也是可以无限使用的。最大连续邮资就相当于一个背包容量,d[i]表示当最大连续邮资为i时所需要的最少的邮票数量,如果d[i]>s,说明 i 是无法凑成的,最大连续邮资也就是 i-1 了

 1 #include<iostream> 
 2 #include<string>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 25;
 8 const int INF = 0x3f3f3f3f;
 9 
10 int s, n, m;
11 int a[maxn];
12 int dp[1005];
13 int ans[25];
14 
15 
16 int main()
17 {
18     //freopen("D:\\txt.txt", "r", stdin);
19     while (cin >> s && s)
20     {
21         int best = 0;         //最大连续邮资
22         int Max=INF;          //最大邮票的值
23         int number = INF;     //邮票数量
24         cin >> n;
25         for (int i = 0; i < n; i++)
26         {
27             cin >> a[0];
28             for (int j = 1; j <= a[0]; j++)
29                 cin >> a[j];
30             memset(dp, INF, sizeof(dp));
31             dp[0] = 0;
32             int now = 0;
33             for (int j = 1; j <= s*a[a[0]]+1; j++)
34             {
35                 for (int k = 1; k <= a[0] && j >= a[k]; k++)
36                     dp[j] = min(dp[j], dp[j - a[k]] + 1);
37                 if (dp[j]>s)
38                 {
39                     now = j - 1;
40                     break;
41                 }
42             }
43             if (now > best)   //此时的最大连续邮资大于了之前的
44             {
45                 best = now;
46                 number = a[0];
47                 Max = a[a[0]];
48                 memcpy(ans, a, sizeof(a));
49             }
50             else if (now == best)   //如果相等时
51             {
52                 if (a[0] < number)   //首先考虑邮票数量少的
53                 {
54                     number = a[0];
55                     Max = a[a[0]];
56                     memcpy(ans, a, sizeof(a));
57                 }
58                 else if (a[a[0]] < Max)   //如果邮票数量一样多,则优先考虑邮票最大的那张更小的
59                 {
60                     Max = a[a[0]];
61                     memcpy(ans, a, sizeof(a));
62                 }
63             }
64         }
65         printf("max coverage =%4d :", best);
66         for (int i = 1; i <= number; i++)printf("%3d", ans[i]);
67         puts("");
68     }
69     return 0;
70 }

 

UVa 242 邮票和信封(完全背包)

标签:eof   over   return   number   背包   ...   思路   style   uva   

原文地址:http://www.cnblogs.com/zyb993963526/p/6380042.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!