我太菜了,看了标签是背包还不知道是怎么回事qaq
看了下题解,意识到这是个类似素数筛的东西。
感性理解可以发现,原货币系统中能被表示出来的是可以不选的,剩下的就是要选的。所以最小的一定要选,把原货币系统从小到大排序。
枚举原货币系统中的货币a[i],枚举金额j(a[i]+1<j<a[n])
如果j-a[i]可以表示,那么通过a[i],j就也可以表示了。用这种方式判断。
核心代码
for(int i = 1; i <= n; i++) {
if(vis[a[i]]) continue;
vis[a[i]] = true;
ans++;
for(int j = a[i]+1; j <= a[n]; j++)
if(vis[j-a[i]]) vis[j] = true;
}
唉——代码好短

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
#include<algorithm>
using namespace std;
const int maxn = 30005;
int t,n,a[maxn],vis[maxn],ans;
void init() {
ans = 0;
memset(a,0,sizeof(a));
memset(vis,0,sizeof(vis));
}
int main() {
scanf("%d",&t);
while(t--) {
init();
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(int i = 1; i <= n; i++) {
if(vis[a[i]]) continue;
vis[a[i]] = true;
ans++;
for(int j = a[i]+1; j <= a[n]; j++)
if(vis[j-a[i]]) vis[j] = true;
}
printf("%d\n",ans);
}
return 0;
}
