【题目描述】
给定一个信封,最多只允许粘贴N(N≤100)张邮票,我们现在有M(M≤100)种邮票,面值分别为:X1,X2……Xm(Xi≤255为正整数),并假设各种邮票都有足够多张。
要求计算所能获得的邮资最大范围。即求最大值MAX,使1-MAX之间的每一个邮资都能得到。
例如:N=4,有2种邮票,面值分别为1分,4分,于是可以得到1-10分和12分,13分,16分邮资,由于得不到11分和15分,所以邮资的最大范围max=10
【输入格式】
第一行为最多粘贴的邮票张数n。第二行为邮票种数m。以下m行各有一个数字表示邮票的面值。
【输出格式】
仅一个数,最大的max的值。
【输入样例】
4
2
1
4
【输出样例】
10
【时间限制】
最大测试点0.5s
用的搜索做的,不知道对不对,求教。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cmp(int a, int b)
{
return a < b;
}
int n, m;
int stamp[105];
bool vis[25500+5];
void solve(int num, int bal)
{
vis[bal] = true;
if (num == n) return;
for (int i = 1; i <= m; ++i)
{
solve(num+1, bal+stamp[i]);
}
}
int main()
{
int maxn, ans = 0;
scanf("%d%d", &n, &m);
memset(vis, false, sizeof(vis));
for (int i = 1; i <= m; ++i)
{
scanf("%d", &stamp[i]);
vis[stamp[i]] = true;
//printf("s[%d]:%d v[%d]:%d\n", i, stamp[i], i, vis[stamp[i]]);
}
sort(stamp+1, stamp+m+1, cmp);
maxn = stamp[m]*n;
vis[0] = true;
vis[maxn] = true;
for (int i = 1; i <= m; ++i)
{
solve(1, stamp[i]);
}
for (int i = 1; i <= maxn + 1; ++i)
{
//printf("vis[%d]:%d\n", i, vis[i]);
if (vis[i] == false)
{
//printf("vis[%d]is ok\n", i);
ans = i-1;
break;
}
}
printf("%d\n", ans);
return 0;
}