邮票组合
Posted lllyclh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了邮票组合相关的知识,希望对你有一定的参考价值。
1.问题描述
邮局有4种不同面值的邮票,在每个信封上最多能贴5张邮票,面值可以相同也可以不同,要求编程出用这4种面值所能组成的邮资的最大值。
2.问题分析
邮票可以取0,1,2,3,4,5张,一共五张可以采用穷举法
假设邮票有a,b,c,d四种面值的
i为a的张数,j为b的张数,k为c的张数,l为d的张数
穷举法组合,然后求出总的邮资
3.程序
#include<iostream> using namespace std; int main() int a, b, c, d, i, j, k, l; static int s[1000];//邮资 cin >> a >> b >> c >> d;//输入四种面值邮票
for (i = 0; i <= 5; i++)//i控制a面值邮票的张数,最多5张 for (j = 0; i + j <= 5; j++)//j控制b面值邮票张数,a+b最多5张 for (k = 0; k + i + j <= 5; k++)//k控制c面值邮票张数,a+b+c最多5张 for (l = 0; k + i + j + l <= 5; l++)//l控制d面值邮票张数,a+b+c+d最多5张 if (a * i + b * j + c * k + d * l) s[a * i + b * j + c * k + d * l]; for (i = 1; i <= 1000; i++) if (!s[i]) break; cout << --i << endl; return 0;
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 }
以上是关于邮票组合的主要内容,如果未能解决你的问题,请参考以下文章