版权声明:本文为博主原创文章。 https://blog.csdn.net/qq_37657307/article/details/84196369
考试的时候理解错了题目,以为交易中是可以找零的,第一组样例也说得通(19=10*4-3*7)。
后来发现如果这样的话第二组样例就错了(13=11+19-17),我才看到了题目中的t[i]是非负整数。
于是转换题意,问你一个序列中最多有多少个数能被其他数表示(只能相加,每个数个数无限)。
显然最小的数无法被表示,于是把数列排序后从最小的数开始做完全背包,每加入一个数就判断一次。
极限时间复杂度O(T*N*A[i])=20*100*25000=50000000,但这是远远达不到的。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int a[105],n,ans;
bool f[25005];
int main()
{
//freopen("money.in","r",stdin);
//freopen("money.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
memset(f,0,sizeof(f));
f[0]=1;
int mx=a[n];
for(int i=1;i<=n;i++)
{
if(f[a[i]])
continue;
ans++;
for(int j=a[i];j<=mx;j++)
f[j]|=f[j-a[i]];
}
printf("%d\n",ans);
}
return 0;
}