背包 || 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 }
View Code

By:AlenaNuna

猜你喜欢

转载自www.cnblogs.com/AlenaNuna/p/11804477.html