11068: 【原1068】小X的邮票
题目
题目描述
author: 寿鹤鸣 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1068
Description
小X喜欢收集邮票,已知一个N枚邮票的面值集合(如,{ 1分,3分 })和一个上限K-表示信封上能够贴K张邮票。计算从1到M的最大连续可贴出的邮资。例如,假设有1分和3分的邮票;最多可以贴5张邮票。很容易贴出1到5分的邮资(用1分邮票贴就行了),接下来的邮资也不难:
6 = 3 + 3 7 = 3 + 3 + 1 8 = 3 + 3 + 1 + 1 9 = 3 + 3 + 3 10 = 3 + 3 + 3 + 1 11 = 3 + 3 + 3 + 1 + 1 12 = 3 + 3 + 3 + 3 13 = 3 + 3 + 3 + 3 + 1。
然而,使用 5 枚 1 分或者 3 分的邮票根本不可能贴出 14 分的邮资。因此,对于这两种邮票的集合和上限 K=5,答案是 M=13。
Input Format
两个整数,K 和 N
K( \(1 \leq K \leq 200\) )是可用的邮票总数。
N( \(1 \leq N \leq 50\) )是邮票面值的数量。
Output Format
N 个整数,每行 15 个,列出所有的 N 个邮票的面值,面值不超过 10000。
Hint
Sample Input
5 2
1 3
Sample Output
13
FineArtz's solution
/* 小X的邮票 */
#include <iostream>
using namespace std;
int k, n, m = 0, ans = 0;
int a[205] = {0}, f[2000005] = {0};
int main(){
cin >> k >> n;
for (int i = 1; i <= n; ++i){
cin >> a[i];
f[a[i]] = 1;
if (a[i] > m)
m = a[i];
}
for (int i = 1; i <= m * k; ++i)
if (f[i] == 0)
f[i] = 500;
ans = m * k;
for (int i = 1; i <= m * k; ++i){
for (int j = 1; j <= n; ++j){
f[i + a[j]] = min(f[i + a[j]], f[i] + 1);
}
if (f[i] > k){
ans = i - 1;
break;
}
}
cout << ans << endl;
return 0;
}
yyong119's solution
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define MAX_N 55
#define MAX_K 205
#define MAX_VALUE 2000005
using namespace std;
queue<int> q;
bool d[MAX_VALUE];
int val[MAX_N];
int n, k;
inline int read() {
char ch = getchar(); int res = 0, flag = 1;
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') flag = -1, ch = getchar();
while (ch >= '0' && ch <= '9')
res = res * 10 + ch - '0', ch = getchar();
return res;
}
int main() {
k = read(); n = read();
for (int i = 0; i < n; ++i) val[i] = read();
q.push(0);
for (int i = 1; i <= k; ++i) {
int cnt = q.size();
for (int x = 0; x < cnt; ++x) {
int v = q.front(); q.pop();
for (int j = 0; j < n; ++j) {
int v_tmp = v + val[j];
if (!d[v_tmp]) {
q.push(v_tmp);
d[v_tmp] = true;
}
}
}
}
for (int i = 1; i < MAX_VALUE; ++i)
if (!d[i]) {
printf("%d\n", i - 1);
break;
}
return 0;
}