zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ",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
    ",ans);
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    c# 深拷贝与浅拷贝
    SQLServer性能优化 .net开发菜鸟总结
    Ajax自定义无刷新控件实现
    APScheduler库的详细用法
    catkin在centos中的安装
    第五次任务实现与项目总结第六组
    Javascript教程:获取当前地址栏url
    窗口处理问题
    HTML中area标签
    Asp.net中Frameset的使用小结
  • 原文地址:https://www.cnblogs.com/Juve/p/11675207.html
Copyright © 2011-2022 走看看