这道题怎么说是一个还算可以下手,我当时想可以初始化全部数组,然后将一开始存在的金额存一个数组,然后将可以通过初始金额累加的金额再存到一个额外的数组。最后剩余的即为不可以表示金额。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define scy(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
int mon[25001]={};
/*
mon[i]=0 表示i面值的钱不能被凑出来
mon[i]=1 表示i面值的钱可以被凑出来
mon[i]=2 表示i面值的钱是货币系统中本来就有的钱
*/
int coins[101]={};//存钱的面值
int T,n,ans=0;
int main(){
scy("in");
scanf("%d ",&T);
while (T--)
{
ans=0;
memset(mon,0,sizeof(mon));
memset(coins,0,sizeof(coins));
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&coins[i]);
mon[coins[i]]=2;
}
//把货币系统中的钱标好
sort(coins+1,coins+1+n);
for (int i=1;i<=coins[n];i++)
{
if (mon[i]>0)
//如果mon[i]能被凑出来
//那么mon[i+coins[j]]也能被凑出来
{
for (int j=1;j<=n;j++)
if (i+coins[j]<=coins[n])
//防止数组越界
mon[i+coins[j]]=1;
else break;
}
}
for (int i=1;i<=coins[n];i++)
if (mon[i]==2) ans++;
printf("%d
",ans);
}
}