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

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 }
时间: 2024-10-26 08:19:39

UVa 242 邮票和信封(完全背包)的相关文章

UVa 242 Stamps and Envelope Size (无限背包,DP)

题意:信封上最多贴S张邮票.有N个邮票集合,每个集合有不同的面值.问哪个集合的最大连续邮资最 大,输出最大连续邮资和集合元素. 最大连续邮资是用S张以内邮票面值凑1,2,3...到n+1凑不出来了,最大连续邮资就是n.如果不止一个集合结果相 同,输出集合元素少的, 如果仍相同,输出最大面值小的. 析:这个题,紫书上写的不全,而且错了好几次,结果WA好几次. 首先这个和背包问题差不多,我们只用一维就好.dp[i]表示邮资为 i 时的最小邮票数,然后,如果dp[i] > s就该结束了. 其他的就很简

uva 11137 Ingenuous Cubrency (完全背包)

uva 11137 Ingenuous Cubrency People in Cubeland use cubic coins. Not only the unit of currency is called a cube but also the coins are shaped like cubes and their values are cubes. Coins with values of all cubic numbers up to 9261 (= 21 3), i.e., coi

UVA 10306 (二维完全背包)

UVA 10306 题意:有种新货币,它的价值有两个值 x 和 y,有一种 e-modulus 值, 计算方式为 sqrt(X*X + Y*Y); 其中 X 和 Y 分别是所有货币 x 值的总和 和 y 值的总和,即 (x1 + x2 +... +xm)^2 + (y1 + y2 +...+ym)^2 = s^2;给出 e-modulus 的值 s , 每种货币的数量无限, 求满足 S 值的货币的最小数量. 输入:第一行输入 n , n 组测试:第二行 m , s :表示有 m 中货币,e-mo

uva 10465 Homer Simpson (完全背包)

uva 10465 Homer Simpson 题目大意:有两种汉堡,给出吃每种汉堡的时间,以及总时间.求出在充分利用时间的前提下,能吃的最多的汉堡数量.当无法利用所有时间时,再在汉堡数量后面输出剩余的时间. 解题思路:完全背包. #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> typedef long lo

uva 242

242 - Stamps and Envelope Size Time limit: 3.000 seconds  Stamps and Envelope Size  Philatelists have collected stamps since long before postal workers were disgruntled. An excess of stamps may be bad news to a country's postal service, but good news

UVA 562 Dividing coins (01背包基础)

[题目链接]:click here~~ 代码: /* * Problem: UVA No.562 * Running time: 0MS * Complier: C++ * Author: ACM_herongwei * Create Time: 11:12 2015/9/9 星期三 * zeroonebags * 将金币总价值的一半作为背包容量,然后zeronebags */ #include <stdio.h> #include <iostream> #include <

UVa 12563 劲歌金曲(0-1背包)

https://cn.vjudge.net/problem/UVA-12563 题意:求在给定时间内,最多能唱多少歌曲,在最多歌曲的情况下,使唱的时间最长. 思路:很明显背包容量为t-1,因为至少得留下1秒钟来放<劲歌金曲>.题目要求的首先唱的歌要多,其次才是要时间长. 这里需要用到一个技巧:对决策进行一定的限定!在计算某个时间最多唱的歌曲时,必须是该时间内恰好唱完这些歌,时间多了不行. 所以在下面的代码中,首先将d数组都声明为了-1,如果不是在该时间内正好唱完歌,那么d[j - a[i]]

UVa 674 Coin Change(完全背包)

https://vjudge.net/problem/UVA-674 题意: 计算兑换零钱的方法共有几种. 思路: 完全背包基础题. 1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 int d[7500]; 8 int a[5] = { 1, 5, 10, 25, 50 }; 9 10 in

UVA 10306 e-Coins(二维完全背包)

At the Department for Bills and Coins, an extension of today's monetary system has newly been proposed, in order to make it fit the new economy better. A number of new so called e-coins will be produced, which, in addition to having a value in the no