题目分析:
找到最小的m,使得b[1]~b[m]能够把a[1] ~a[n]表示的货币表示出来,而a不能表示出来的货币也表示不出来。
思路:
思路:
从a[]中选b[]。
从小到大判断ai能否被1~ai-1 表示出来,如果能表示i出来,就把ai除去,否则加进b[]。
把ai的值当作总体积,从前i-1个物品中选,当不能够表示ai(f[a[i]] == 0),增加b的容量res,最后答案就是b的总容量m。
由于每个a可以选择无数次,因此是一个完全背包。
f[I, a[i]]: 从前I - 1个物品中选,总体积是a[i]的背包, 能够装满的方案数(如果是0,代表没有方案能装满b)。
状态方程:
f[k, j] += f[k, j - a[k]] k = 1~I - 1
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int N = 110, M = 25010;
int f[M], a[N];
int main()
{
int T; cin >> T;
while(T--)
{
int n; cin >> n;
for(int i = 1; i <= n; ++i)
{
cin >>a[i];
}
sort(a + 1, a + n + 1);
int res = 0;
memset(f, 0, sizeof f);
f[0] = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = a[i]; j <= a[n]; ++j)
{
f[j] += f[j - a[i]];
//cout << j << " " << f[j] <<endl;
}
if(f[a[i]] == 1)res++;
}
/* for(int i = 1; i <= n; ++i)
if(f[a[i]] == 0)res++;*/
cout << res <<endl;
}
return 0;
}