Luogu P5020 货币系统

Luogu P5020 货币系统

先把$a$数组排一下序。
从最小的数开始选,显然最小这个数必须选,然后利用完全背包的思想,从$a_i$到最大值筛选一遍,将可以组成的打上标记。
在判断后面的数字时,如果已经被标记过了,就不再选,没有被标记过就标记一下,再筛选一次数(即再做一次完全背包)。

#include<bits/stdc++.h>
#define N 110
#define A 25010

using namespace std;

int t,n,ans,mmax;
int a[N];
bool vis[A];

void Init() {
	mmax=0;
	ans=0;
	memset(vis,0,sizeof(vis));
	return;
}

void Read() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%d",&a[i]);
		mmax=max(mmax,a[i]);
	}
	return;
}

void Backpack() {
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++) {
		if(vis[a[i]]) {
			continue;
		}
		ans++;
		vis[a[i]]=1;
		for(int j=a[i];j<=mmax;j++) {
			if(vis[j-a[i]]) {
				vis[j]=1;
			}
		}
	}
	return;
}

void Print() {
	printf("%d\n",ans);
	return;
}

int main()
{
	scanf("%d",&t);
	for(int i=1;i<=t;i++) {
		Init();
		Read();
		Backpack();
		Print();
	}
	return 0;
}
posted @ 2019-10-05 14:59  WalkerV  阅读(104)  评论(0编辑  收藏  举报