【NOIP2018提高组D1T2】货币系统

这题就是送分的。直接记忆化深搜即可
但有些人竟然跟我打的不一样,我也贴一下标吧

深搜:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int T,n,a[101],b[101],m,ans;
int bz[25001];

void dg(int x,int now)
{
	for (int i=now;i<=m && b[i]<=x;i++)
		for (int j=b[i];j<=x;j+=b[i])
		{
			if (!bz[x-j]) dg(x-j,now+1);
			if (bz[x-j]==2) {bz[x]=2; return;}
		}
	bz[x]=1;return;
}

bool pd(int x)
{
	for (int i=1;i<=m;i++)
		if (a[x]%b[i]==0) return 0;
	return 1;
}

int main()
{
	freopen("money.in","r",stdin);
	freopen("money.out","w",stdout);
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d",&n);m=ans=0;
		for (int i=1;i<=n;i++) scanf("%d",&a[i]);
		memset(bz,0,sizeof(bz));
		sort(a+1,a+n+1);
		for (int i=1;i<=n;i++)
			if (pd(i)) b[++m]=a[i];
		for (int i=1;i<=m;i++)
		{
			dg(b[i],1);
			if (bz[b[i]]==1) ans++,bz[b[i]]=2;
		}
		printf("%d
",ans);
	}
	return 0;
}

其他方法:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define max(x,y) x=x>y?x:y
using namespace std;
int a[102];
bool bz[25001];

int cmp(int x,int y) {return x<y;}

int main()
{
	freopen("money.in","r",stdin);
	freopen("money.out","w",stdout);
	int n,T,l,ans,p;
	scanf("%d",&T);
	for (;T;T--)
	{
		scanf("%d",&n);
		l=1;ans=0;p=-1;
		for (int i=1;i<=n;i++) scanf("%d",&a[i]),max(p,a[i]);
		sort(a+1,a+n+1,cmp);
		memset(bz,0,sizeof(bz));
		for (int i=1;i<=p&&l<=n;i++)
		{
			while (bz[a[l]]) l++;
			if (a[l]==i&&!bz[i])
			{
				while (a[l]==i) l++;
				ans++;bz[a[l-1]]=true;
			}
			if (bz[i]) for (int j=1;j<=n&&i+a[j]<=p;j++) bz[i+a[j]]=true;
		}
		printf("%d
",ans);
	}
}
转载需注明出处。
原文地址:https://www.cnblogs.com/jz929/p/11817844.html