背包 || NOIP 2018 D1 T2 || Luogu P5020 货币系统
题面:P5020 货币系统
题解:
显然要求的货币系统是当前货币系统的子集时答案会更优,于是考虑从当前货币系统中删数
一个大数如果能被其他小数表示出来,它就可以去掉
把数据排个序去个重,然后直接背包
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #define max(a,b) ((a)>(b)?(a):(b)) 5 using namespace std; 6 inline int rd(){ 7 int x=0,f=1; char c=getchar(); 8 while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} 9 while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} 10 return f*x; 11 } 12 const int maxn=105,maxa=25005; 13 int N,T,A[maxn],mx,n,x,ans; 14 bool vis[maxa],book[maxa],flag; 15 int main(){ 16 T=rd(); 17 while(T--){ 18 ans=0; 19 memset(book,0,sizeof(book)); 20 memset(vis,0,sizeof(vis)); 21 vis[0]=1; 22 N=rd(); 23 mx=0; n=0; 24 for(int i=1;i<=N;i++){ 25 x=rd(); 26 book[x]=1; 27 mx=max(mx,x); 28 } 29 for(int i=1;i<=mx;i++) 30 if(book[i]) A[++n]=i; //排序+去重 31 for(int i=1;i<=mx;i++){ 32 bool flag=0; 33 for(int j=1;A[j]<=i && j<=n;j++){ 34 if(vis[i-A[j]]){ 35 if(i-A[j]==0) flag=1; 36 vis[i]=1; 37 break; 38 } 39 } 40 if(flag) ans++; 41 } 42 printf("%d\n",ans); 43 } 44 return 0; 45 }
By:AlenaNuna