zoukankan      html  css  js  c++  java
  • 模拟33 题解

    A. 春思

    比较简单的一道题,甚至是见过的原题。

    约数和是积性函数,搞一搞等差数列求和,乘到一起就可以了。

    B. 密州盛宴

    显然,方案合法的条件是苏轼每轮都能吃到菜。

    所以就发现任意后缀0,1个数必须满足,$sufcnt_0-sufcnt_1<=1$。

    所以当不满足条件时找到第一个1,把他交换过来,答案对两者之间的距离取max,显然这样能得到一个最优答案。

    左侧用单调指针,复杂度$O(n)$,过不去。

    然后就发现,直接对$sufcnt0-sufcnt1$取个$max$,然后输出$max-1$就可以了。

    这个取max的操作是等价于上述的单调指针算法的。

    因为任何交换不影响交换之前的点的$sufcnt$,

    一个交换,两点之间的距离一定可以表示为交换的1的$sufcnt_0-sufcnt_1-1$。

    C. 赤壁情

    比较新奇的dp题。

    设$dp(i,j,k,0/1/2)$表示已经插入i个数,形成了j段连续的数,这些数构成的权值为k,已经有了0/1/2个数在l或r边界上的方案数。

    值得注意的一点是,利用先插入的数小于后插入的数的值的性质,

    我们将已经插入的数的贡献直接算在了权值中,而不是构成差时再加入,这样才使状态没有了后效性。

    另外,我们在dp的过程中,并不确定每一段的具体位置,只知道它们之间的左右位置关系,和是否接在端点。

    在插入了最后一个数,对于合法方案,具体位置才得到确定。

    五个转移方程,分别对应:

    接在一段旁边,

    连接两段,

    单独成一段,

    放在端点并接上一段,

    单独放在端点。

    在转移中乘上每个方程对应的系数就可以了。

    要求保留30位小数,用高精度。

    在作除法之前将答案左移31位(十进制),第31位表示小数点后的第一位。

    最后根据最后一位的大小决定是否要进位。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<iomanip>
      5 using namespace std;
      6 int n,m,k;
      7 namespace DOUBLE{
      8     const int N=105;
      9     double dp[2][N*N][N/2][3],ans;
     10     void go(){
     11         int cur=1; const int base=n*(n+1)/2;
     12         dp[cur][base-2][1][0]=1;
     13         dp[cur][base-1][1][1]=2;
     14         dp[cur][base][1][2]=1;
     15         for(int i=2;i<=n;++i){
     16             cur^=1;
     17             const int lm=min(i,n-i+1)+1;
     18             for(int j=0;j<=2*base;++j)
     19                 for(int k=1;k<=lm;++k)
     20                     for(int u=0;u<3;++u) dp[cur][j][k][u]=0;
     21             for(int j=0;j<=2*base;++j)
     22                 for(int k=1;k<=lm;++k)
     23                     for(int u=0;u<3;++u){
     24                         dp[cur][j][k][u]+=dp[cur^1][j][k][u]*(k*2-u);//接在后面
     25                         if(j+2*i<=2*base) dp[cur][j+2*i][k-1][u]+=dp[cur^1][j][k][u]*(k-1);//合并
     26                         if(j-2*i>=0) dp[cur][j-2*i][k+1][u]+=dp[cur^1][j][k][u]*(k+1-u);//单独
     27                         if(j+i<=2*base&&u!=2) dp[cur][j+i][k][u+1]+=dp[cur^1][j][k][u]*(2-u);//接在一端
     28                         if(j-i>=0&&u!=2) dp[cur][j-i][k+1][u+1]+=dp[cur^1][j][k][u]*(2-u);//在一端单独开
     29                     }
     30         }
     31         for(int i=m+base;i<=2*base;++i) ans+=dp[cur][i][1][2];
     32         for(int i=1;i<=n;++i) ans/=i;
     33         cout<<fixed<<setprecision(k)<<ans<<endl;
     34     }
     35 }
     36 namespace BIGINT{
     37     const int N=55;
     38     struct BigInteger{
     39         const static long long base=1e10;
     40         long long s[12];
     41         int num;
     42         void set(int x){
     43             memset(s,0,sizeof(s));
     44             s[num=1]=x;
     45         }
     46         friend void operator +=(BigInteger &a,BigInteger b){
     47             a.num=max(a.num,b.num);
     48             for(int i=1;i<=a.num;++i){
     49                 a.s[i]+=b.s[i];
     50                 if(a.s[i]>=base) a.s[i]-=base,++a.s[i+1];
     51             }
     52             if(a.s[a.num+1]) ++a.num;
     53         }
     54         friend BigInteger operator *(BigInteger a,int x){
     55             int j=0;
     56             for(int i=1;i<=a.num;++i){
     57                 a.s[i]=a.s[i]*x+j;
     58                 j=a.s[i]/base;
     59                 a.s[i]%=base;
     60             }
     61             if(j) a.s[++a.num]=j;
     62             return a;
     63         }
     64         friend void operator /=(BigInteger &a,int x){
     65             for(int i=a.num;i;--i){
     66                 a.s[i-1]+=a.s[i]%x*base;
     67                 a.s[i]/=x;
     68             }
     69             if(!a.s[a.num]) --a.num;
     70         }
     71     };
     72     BigInteger dp[2][N*N][N/2][3],ans;
     73     void go(){
     74         int cur=1; const int base=n*(n+1)/2;
     75         dp[cur][base-2][1][0].set(1);
     76         dp[cur][base-1][1][1].set(2);
     77         dp[cur][base][1][2].set(1);
     78         for(int i=2;i<=n;++i){
     79             cur^=1;
     80             const int lm=min(i,n-i+1)+1;
     81             for(int j=0;j<=2*base;++j)
     82                 for(int k=1;k<=lm+1;++k)
     83                     for(int u=0;u<3;++u) dp[cur][j][k][u].set(0);
     84             for(int j=0;j<=2*base;++j)
     85                 for(int k=1;k<=lm;++k)
     86                     for(int u=0;u<3;++u){
     87                         dp[cur][j][k][u]+=dp[cur^1][j][k][u]*(k*2-u);//接在后面
     88                         if(j+2*i<=2*base) dp[cur][j+2*i][k-1][u]+=dp[cur^1][j][k][u]*(k-1);//合并
     89                         if(j-2*i>=0) dp[cur][j-2*i][k+1][u]+=dp[cur^1][j][k][u]*(k+1-u);//单独
     90                         if(j+i<=2*base&&u!=2) dp[cur][j+i][k][u+1]+=dp[cur^1][j][k][u]*(2-u);//接在一端
     91                         if(j-i>=0&&u!=2) dp[cur][j-i][k+1][u+1]+=dp[cur^1][j][k][u]*(2-u);//在一端单独开
     92                     }
     93         }
     94         for(int i=m+base;i<=2*base;++i) ans+=dp[cur][i][1][2];
     95         for(int i=1;i<=k+10;++i) ans=ans*10;
     96         for(int i=1;i<=n;++i) ans/=i;
     97         if(ans.s[1]>=ans.base/2) ++ans.s[2];
     98         for(int i=2;i<=ans.num;++i)
     99             if(ans.s[i]>=ans.base) ans.s[i]-=ans.base,++ans.s[i+1];
    100         printf("%lld.",ans.s[5]);
    101         for(int i=4;i>1;--i) printf("%010lld",ans.s[i]);
    102         puts("");
    103     }
    104 }
    105 int main(){
    106     scanf("%d%d%d",&n,&m,&k);
    107     if(k>=10) BIGINT::go();
    108     else DOUBLE::go();
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    Javescript基础api实现原理
    React Fiber
    ASP.NET中Form验证登录后反复跳转回登录页面的问题
    跨域部署Silverlight时需要注意的问题
    Windows 8 x64+Ruby 2上安装Sqlite3方法
    .NET 项目在源码控制中程序集的引用问题
    [EntLib]解决The type or namespace name 'Data' does not exist in the namespace 'Microsoft.Practices.EnterpriseLibrary' 的错误
    ASP.NET MVC Url中参数过长引发的问题
    Windows 8 x64 QQ2012/2013beta无法启动屌丝解决方法
    TechEd 2010参会小记
  • 原文地址:https://www.cnblogs.com/skyh/p/11451884.html
Copyright © 2011-2022 走看看