链接
题目描述
给你一些数字,这堆数字无论哪个数选多少个都可以,然后就会有一些数能凑出,一些不能。
要你再找一堆尽可能少的数字,使得它像前面那样凑能凑出的和不能凑出的是一模一样的。
输出你找的这堆最少个数的数字的个数。
样例输入
2
4
3 19 10 6
5
11 29 13 19 17
样例输出
2
5
思路
完全背包
我们的m一开始设为n,然后找a[i]里有多少可以被表示出来,m随之减小,那么就可以得到最后的答案了
枚举过程中把可以得到的数值标记了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int T, n;
int f[10000005], a[10000005];
int main()
{
scanf("%d", &T);
for(int t = 1; t <= T; ++t)
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
memset(f, 0, sizeof(f));
sort(a + 1, a + n + 1);
f[0] = 1;
int ans = n;
for(int i = 1; i <= n; ++i)
{
if(f[a[i]]) {
ans--;
continue;
}
for(int j = a[i]; j <= a[n]; ++j)
f[j] |= f[j - a[i]];
}
printf("%d\n", ans);
}
return 0;
}