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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章