货币系统

这道题怎么说是一个还算可以下手,我当时想可以初始化全部数组,然后将一开始存在的金额存一个数组,然后将可以通过初始金额累加的金额再存到一个额外的数组。最后剩余的即为不可以表示金额。

#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);
	}
}
原文地址:https://www.cnblogs.com/scy-fisheep/p/13810577.html