这题就是送分的。直接记忆化深搜即可
但有些人竟然跟我打的不一样,我也贴一下标吧
深搜:
#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);
}
}