uva242

题目描述:假定一张信封最多贴5张邮票,如果只能贴1分和3分的邮票,可以组成面值1~13以及 15,但不能组成面值14。我们说:对于邮票组合{1,3}以及数量上限S=5,最大连续邮资为 13。

输入S(S≤10)和若干邮票组合(邮票面值不超过100),选出最大连续邮资最大的一个 组合。如果有多个并列,邮票组合中邮票的张数应最多。如果还有并列,邮票从大到小排序 后字典序应最大。

分析:完全背包,因为组成最大的连续面值为100*10=1000,所以可以用数组下标存储。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<sstream>
#include<cassert>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1000+10;
int d[10+5][maxn];
int s;
int a[10 + 5][10 + 5];
int dp(int i1,int i2) {
	int ok = 0;
	d[i1][0] = 0;
	for (int i = 1; i; i++) {
		for (int j = 0; j < i2; j++) {
			if (i - a[i1][j] >= 0) {
				ok = 1;
				 if (d[i1][i - a[i1][j]] !=-1) {					
					d[i1][i] = min(d[i1][i],d[i1][i - a[i1][j]] + 1);
				}
			}
		}
		if (d[i1][i]>s)return i - 1;
	}
}
int main() {
	int n;
	while (cin >> s && s) {
		cin >> n;
		int num[10+5];
		memset(d, INF, sizeof(d));
		for (int i = 0; i < n; i++) {
			cin >> num[i];
			for (int j = 0; j < num[i]; j++)
				cin >> a[i][j];
		}
		int ans = 0;
		int cnt = 0;
		for (int i = 0; i < n; i++) {
			int t = dp(i, num[i]);
			if (t > ans) {
				ans = t; cnt = i;
			}
			if (t == ans) {
				int n1 = num[cnt], n2 =num[i];
				if (n1 > n2) {
					cnt = i;
				}
				else if (n1 == n2) {
					while (n1-- > 0) {
						if (a[cnt][n1] > a[i][n1]) {
							cnt = i; break;
						}
						else if (a[cnt][n1] < a[i][n1])break;
					}
				}
			}
		}
		printf("max coverage =%4d :", ans);
		for (int i = 0; i < num[cnt]; i++) {
			printf("%3d", a[cnt][i]);
		}
		cout << endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值