$Noip2018/Luogu5020$ 货币系统 $dp$

$Luogu$

 

去年我这题获得了$20$的好分数$ovo..........$

 

$Sol$

现在来看其实非常显然叭,只要把能被别的数表示出来的数去掉就好了.

$f[i]$表示$i$数能否被其他数表示.完全背包就好辣.但有一点不同的是$f[i]$是能否被其他数表示,而不是能否被表示.把$a[i]$从小到大排序,最外层循环到$a[i]$时检查$f[i]$是否为$1$,累计答案.

 

$Code$

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define il inline
#define Rg register
#define go(i,a,b) for(Rg int i=a;i<=b;++i)
#define yes(i,a,b) for(Rg int i=a;i>=b;--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Rg int x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
int T,n,ms,as,a[110];
bool f[25010];
int main()
{
    T=read();
    while(T--)
    {
        n=read();go(i,1,n)a[i]=read();
        sort(a+1,a+n+1);
        ms=a[n];as=0;mem(f,0);
        go(i,1,n)
        {
            if(f[a[i]])continue;
            as++,f[a[i]]=1;
            go(j,a[i],ms)if(f[j-a[i]])f[j]=1;
        }
        printf("%d\n",as);
    }
    return 0;
}
View Code

 

 

 

posted @ 2019-08-24 10:16  DTTTTTTT  阅读(125)  评论(0编辑  收藏  举报