每日一题 day7 打卡
Analysis
完全背包+筛法
只用完全背包会超时,所以要用筛法的思想来优化:筛去所有可以用已知货币系统中的面值表示出来的金额
80分 不用筛法
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 100+10 6 #define maxnum 25000+10 7 #define INF 2147483647/2-1 8 using namespace std; 9 inline int read() 10 { 11 int x=0; 12 bool f=1; 13 char c=getchar(); 14 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 15 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 16 if(f) return x; 17 return 0-x; 18 } 19 inline void write(int x) 20 { 21 if(x<0){putchar('-');x=-x;} 22 if(x>9)write(x/10); 23 putchar(x%10+'0'); 24 } 25 int T; 26 int n,ans; 27 int a[maxn],dp[maxnum]; 28 inline bool check(int x) 29 { 30 memset(dp,0,sizeof(dp)); 31 for(int i=1;i<x;i++) 32 for(int j=a[i];j<=a[x];j++) 33 dp[j]=max(dp[j-a[i]]+a[i],dp[j]); 34 if(dp[a[x]]==a[x]) return false; 35 return true; 36 } 37 int main() 38 { 39 T=read(); 40 while(T--) 41 { 42 memset(dp,0,sizeof(dp)); 43 n=read(); 44 ans=n; 45 for(int i=1;i<=n;i++) a[i]=read(); 46 sort(a+1,a+n+1); 47 for(int i=2;i<=n;i++) if(check(i)==false) ans--; 48 write(ans); 49 printf(" "); 50 } 51 return 0; 52 }
100分 筛法
mark[i]=0 表示i面值的钱不能被凑出来
mark[i]=1 表示i面值的钱可以被凑出来
mark[i]=2 表示i面值的钱是货币系统中本来就有
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 100+10 6 #define maxnum 25000+10 7 #define INF 2147483647/2-1 8 using namespace std; 9 inline int read() 10 { 11 int x=0; 12 bool f=1; 13 char c=getchar(); 14 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 15 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 16 if(f) return x; 17 return 0-x; 18 } 19 inline void write(int x) 20 { 21 if(x<0){putchar('-');x=-x;} 22 if(x>9)write(x/10); 23 putchar(x%10+'0'); 24 } 25 int T; 26 int n,ans; 27 int a[maxn],mark[maxnum]; 28 int main() 29 { 30 T=read(); 31 while(T--) 32 { 33 memset(mark,0,sizeof(mark)); 34 n=read(); 35 ans=n; 36 for(int i=1;i<=n;i++) 37 { 38 a[i]=read(); 39 mark[a[i]]=2; 40 } 41 sort(a+1,a+n+1); 42 for(int i=1;i<=a[n];i++) 43 if(mark[i]>0) 44 for(int j=1;j<=n;j++) 45 { 46 if(i+a[j]<=a[n]) mark[i+a[j]]=1; 47 else break; 48 } 49 for(int i=2;i<=n;i++) if(mark[a[i]]==1) ans--; 50 write(ans); 51 printf(" "); 52 } 53 return 0; 54 }
请各位大佬斧正(反正我不认识斧正是什么意思)