csps模拟测试707172部分题解myc

题面:https://www.cnblogs.com/Juve/articles/11678524.html

骆驼:构造题,留坑

根据5×5的矩形构造成大矩形

毛一琛:

mid in the middle思想,先dfs一半,然后dfs后一半

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<unordered_map>
 6 #include<set>
 7 #define int long long
 8 #define re register
 9 using namespace std;
10 const int MAXN=23;
11 int n,m[MAXN],ans=0,tot=0;
12 unordered_map<int,int>mp;
13 set<int>s[1<<23];
14 bool vis[1<<23];
15 void DFS(re int now,re int num,re int st){
16     if(now>n){
17         if(mp.find(num)==mp.end()) return ;
18         int t=mp[num];
19         for(set<int>::iterator it=s[t].begin();it!=s[t].end();++it){
20             if(vis[(*it)|st]==0) ++ans;
21             vis[(*it)|st]=1;
22         }
23         return ;
24     }
25     DFS(now+1,num,st);
26     DFS(now+1,num+m[now],st|(1<<(now-1)));
27     DFS(now+1,num-m[now],st|(1<<(now-1)));
28 }
29 void dfs(re int now,re int num,re int st){
30     if(now>n/2){
31         int t;
32         if(mp.find(num)==mp.end()) t=mp[num]=++tot;
33         else t=mp[num];
34         s[t].insert(st);
35         return ;
36     }
37     dfs(now+1,num,st);
38     dfs(now+1,num+m[now],st|(1<<(now-1)));
39     dfs(now+1,num-m[now],st|(1<<(now-1)));
40 }
41 signed main(){
42     scanf("%lld",&n);
43     for(re int i=1;i<=n;++i) scanf("%lld",&m[i]);
44     vis[0]=1;
45     dfs(1,0,0);DFS(n/2+1,0,0);
46     printf("%lld\n",ans);
47     return 0;
48 }
View Code

毛二琛:dp,不会

毛三琛:

二分思路考场上想到了,但是没有想到优化骗分

把x随机排个序,二分前先check一下是否比当先的ans优,不优就不二分

再加个clock

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 #define re register
 7 using namespace std;
 8 const int MAXN=1e4+5;
 9 int n,k,p,a[MAXN],res,l=0x3f3f3f3f,r=0,ans=0,x[MAXN],b[MAXN];
10 inline bool check(re int lim){
11     re int tot=0,sum=0;
12     for(re int i=1;i<=n;++i){
13         if(b[i]>lim) return 0;
14         if(sum+b[i]>lim){
15             ++tot;
16             sum=b[i];
17             if(tot>=k) return 0;
18         }else sum+=b[i];
19     }
20     return 1;
21 }
22 signed main(){
23     re double ck=clock();
24     scanf("%lld%lld%lld",&n,&p,&k);
25     for(re int i=1;i<=n;++i){
26         scanf("%lld",&a[i]);
27         r+=a[i],l=min(l,a[i]);
28     }
29     for(re int i=1;i<=p;++i) x[i]=i-1;
30     srand(time(0));
31     random_shuffle(x+1,x+p+1);
32     ans=r;
33     for(re int i=1;i<=p;++i){
34         if(clock()-ck>984000) break;
35         l=1,r=ans;
36         for(re int j=1;j<=n;++j){
37             b[j]=(a[j]+x[i])%p;
38             l=max(l,b[j]);
39         }
40         if(!check(r)) continue;
41         while(l<r){
42             re int mid=(l+r)>>1;
43             if(check(mid)) r=mid;
44             else l=mid+1;
45         }
46         ans=min(ans,l);
47     }
48     printf("%lld\n",ans);
49     return 0;
50 }
View Code

简单的序列:

推式子,dp也可以

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 using namespace std;
 7 const int MAXN=1e5+5,mod=1e9+7;
 8 int n,m,tot=0,ans=0,cnt=0;
 9 char s[MAXN];
10 int max(int a,int b){
11     return a>b?a:b;
12 }
13 int q_pow(int a,int b,int p){
14     int res=1;
15     while(b){
16         if(b&1) res=res*a%p;
17         a=a*a%p;
18         b>>=1;
19     }
20     return res;
21 }
22 int fac(int N){
23     int res=1;
24     for(int i=2;i<=N;++i) res=res*i%mod;
25     return res%mod;
26 }
27 int C(int n,int m){
28     if(m>n) return 0;
29     if(m==n) return 1;
30     return fac(n)*q_pow(fac(m)%mod,mod-2,mod)%mod*q_pow(fac(n-m)%mod,mod-2,mod)%mod;
31 }
32 int sta[MAXN],top=0;
33 signed main(){
34     scanf("%lld%lld%s",&n,&m,s+1);
35     for(int i=1;i<=m;++i){
36         if(s[i]=='(') sta[++top]=1;
37         else if(top) ++cnt,--top;
38     }
39     if(n&1){
40         puts("0");
41         return 0;
42     }
43     ans=C(n-m+1,n/2-m+cnt);
44     printf("%lld\n",ans);
45     return 0;
46 }
View Code

 

简单的期望

dp[i][j][k][0/1]表示操作了i次,最后8位是j,右移8位后最后有连续k位是0/1。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 #define re register
 7 using namespace std;
 8 const int MAXN=205;
 9 int x,n,pre[2005];
10 double p,ans,f[MAXN][(1<<8)+5][235][2];
11 signed main(){
12     scanf("%lld%lld%lf",&x,&n,&p);
13     for(int i=1;i<=(1<<8);++i) pre[i*2]=pre[i]+1;
14     int d=x&1,b=x&255,c=0;
15     x>>=8;p/=100.0;
16     while(x&&(x&1)==d){
17         x>>=1;
18         ++c;
19     }
20     f[0][b][c][d]=1.0;
21     for(int i=1;i<=n;++i){
22         for(int j=0;j<(1<<8);++j){
23             for(int k=0;k<=230;++k){
24                 if(j==((1<<8)-1)){
25                     f[i][0][k][0]+=f[i-1][j][k][1]*(1.0-p);
26                     f[i][0][1][1]+=f[i-1][j][k][0]*(1.0-p);
27                 }else{
28                     f[i][j+1][k][1]+=f[i-1][j][k][1]*(1.0-p);
29                     f[i][j+1][k][0]+=f[i-1][j][k][0]*(1.0-p);
30                 }
31                 if(j>=(1<<7)){
32                     int b=(j<<1)&((1<<8)-1);
33                     int tmp=((j<<1)&(1<<8))>>8;
34                     if(tmp!=0){
35                         f[i][b][k+1][1]+=f[i-1][j][k][1]*p;
36                         f[i][b][1][tmp]+=f[i-1][j][k][0]*p;
37                     }else{
38                         f[i][b][1][tmp]+=f[i-1][j][k][1]*p;
39                         f[i][b][k+1][0]+=f[i-1][j][k][0]*p;
40                     }
41                 }else{
42                     f[i][j<<1][1][0]+=f[i-1][j][k][1]*p;
43                     f[i][j<<1][k+1][0]+=f[i-1][j][k][0]*p;
44                 }
45             }
46         }
47     }
48     for(int j=1;j<=(1<<8);j++){
49         for(int k=0;k<=230;k++)
50             ans+=pre[j]*(f[n][j][k][0]+f[n][j][k][1]);
51     }
52     for(int k=0;k<=230;k++)
53         ans+=((f[n][0][k][1]+f[n][0][k][0])*8)+f[n][0][k][0]*k;
54     printf("%0.6lf\n",ans);
55     return 0;
56 }
View Code

 

posted @ 2019-10-15 16:26  xukl21  阅读(229)  评论(0编辑  收藏  举报