• HZOJ 题


    首先对于n<=100的点,直接暴力dp,f[i][j][k]表示时间为i,在i,j位置的方案数,枚举转移即可,期望得分40。

     1     if(n<=100)
     2     {
     3         if(t==0)
     4         {
     5             f[0][100][100]=1;
     6             for(int i=1;i<=n;i++)
     7                 for(int x=1;x<=200;x++)
     8                     for(int y=1;y<=200;y++)
     9                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
    10             printf("%d
    ",f[n][100][100]);
    11             return 0;
    12         }
    13         if(t==1)
    14         {
    15             f[0][1][0]=1;
    16             for(int i=1;i<=n;i++)
    17                 for(int x=1;x<=101;x++)
    18                     f[i][x][0]=(f[i-1][x-1][0]+f[i-1][x+1][0])%mod;
    19             printf("%d
    ",f[n][1][0]);
    20             return 0;
    21         }
    22         if(t==2)
    23         {
    24             f[0][100][100]=1;
    25             for(int i=1;i<=n;i++)
    26                 for(int x=1;x<=200;x++)
    27                     for(int y=1;y<=200;y++)
    28                         if(x==100||y==100)
    29                             f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
    30             printf("%d
    ",f[n][100][100]);
    31             return 0;
    32         }
    33         if(t==3)
    34         {
    35             f[0][1][1]=1;
    36             for(int i=1;i<=n;i++)
    37                 for(int x=1;x<=n+1;x++)    
    38                     for(int y=1;y<=n+1;y++)
    39                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
    40             printf("%d
    ",f[n][1][1]);
    41             return 0;
    42         }
    43     }
    代码实现

    type0:这里

    type1:显然卡特兰数……

    type2:居然是个dp

    f[i]表示走了i步回到原点的方案数,枚举第一次回到原点时走过的步数j(为了存在合法解,j为偶数),则此时方案数为f[i-j]*catalan(j/2-1),复杂度为O(n^2)所以最大范围只出到1000.

    type3:

    枚举横向移动了多少步.横向移动i步时(为了存在合法解,i必须是偶数),方案数为C(n,i)*catalan(i/2)*catalan((n-i)/2)

    可以这样考虑:横向移动了i步,因为只能在第一象限,所以横向是一个卡特兰数,同理纵向也是一个卡特兰数。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #define LL long long
      5 using namespace std;
      6 const int mod=1e9+7;
      7 int n,t;
      8 int f[110][210][210];
      9 LL f1[1100];
     10 LL jc[100010];
     11 LL poww(LL a,int b,int mod)
     12 {
     13     LL ans=1;
     14     while(b)
     15     {
     16         if(b&1)ans=ans*a%mod;
     17         a=a*a%mod;
     18         b=b>>1;
     19     }
     20     return ans;
     21 }
     22 LL C(int n,int m)
     23 {
     24     if(m>n)return 0;
     25     if(!m)return 1;
     26     return jc[n]*poww(jc[m],mod-2,mod)%mod*poww(jc[n-m],mod-2,mod)%mod;
     27 }
     28 LL H(int i)
     29 {
     30     return C(2*i,i)*poww(i+1,mod-2,mod)%mod;
     31 }
     32 inline int read();
     33 signed main()
     34 {    
     35     n=read(),t=read();
     36     if(n<=100)
     37     {
     38         if(t==0)
     39         {
     40             f[0][100][100]=1;
     41             for(int i=1;i<=n;i++)
     42                 for(int x=1;x<=200;x++)
     43                     for(int y=1;y<=200;y++)
     44                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
     45             printf("%d
    ",f[n][100][100]);
     46             return 0;
     47         }
     48         if(t==1)
     49         {
     50             f[0][1][0]=1;
     51             for(int i=1;i<=n;i++)
     52                 for(int x=1;x<=101;x++)
     53                     f[i][x][0]=(f[i-1][x-1][0]+f[i-1][x+1][0])%mod;
     54             printf("%d
    ",f[n][1][0]);
     55             return 0;
     56         }
     57         if(t==2)
     58         {
     59             f[0][100][100]=1;
     60             for(int i=1;i<=n;i++)
     61                 for(int x=1;x<=200;x++)
     62                     for(int y=1;y<=200;y++)
     63                         if(x==100||y==100)
     64                             f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
     65             printf("%d
    ",f[n][100][100]);
     66             return 0;
     67         }
     68         if(t==3)
     69         {
     70             f[0][1][1]=1;
     71             for(int i=1;i<=n;i++)
     72                 for(int x=1;x<=n+1;x++)    
     73                     for(int y=1;y<=n+1;y++)
     74                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
     75             printf("%d
    ",f[n][1][1]);
     76             return 0;
     77         }
     78     }
     79     else
     80     {
     81         LL ans=0;
     82         jc[0]=1;for(int i=1;i<=100000;i++)jc[i]=jc[i-1]*i%mod;
     83         if(t==0)
     84         {
     85             int s,x,z,y;
     86             for(s=0;s<=n/2;s++)
     87             {
     88                 x=s;z=y=(n-s-x)/2;    
     89                 ans=(ans+jc[n]*poww(jc[s],mod-2,mod)%mod*poww(jc[x],mod-2,mod)%mod*poww(jc[z],mod-2,mod)%mod*poww(jc[y],mod-2,mod)%mod)%mod;
     90             }
     91             printf("%lld
    ",ans%mod);
     92             return 0;
     93         }
     94         if(t==1)
     95         {
     96             n=n/2;ans=1;
     97             for(int i=n+2;i<=2*n;i++)ans=ans*i%mod;
     98             ans=ans*poww(jc[n],mod-2,mod);
     99             printf("%lld
    ",ans%mod);
    100             return 0;
    101         }
    102         if(t==2)
    103         {    
    104             f1[0]=1;
    105             for(int i=2;i<=n;i+=2)
    106                 for(int j=2;j<=i;j+=2)
    107                     f1[i]=(f1[i]+4*f1[i-j]*H(j/2-1)%mod)%mod;
    108             printf("%lld
    ",f1[n]%mod);
    109             return 0;
    110         }
    111         if(t==3)
    112         {
    113             for(int i=0;i<=n;i+=2)
    114                 ans=(ans+C(n,i)*H(i/2)%mod*H((n-i)/2)%mod)%mod;
    115             printf("%lld
    ",ans);
    116             return 0;
    117         }
    118     }
    119 }
    120 inline int read()
    121 {    
    122     int s=0;char a=getchar();
    123     while(a<'0'||a>'9')a=getchar();
    124     while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    125     return s;
    126 }
    暴力和正解全在这里!!

     

  • 相关阅读:
    top指令
    Trie
    最大公约数
    angular2 获取到的数据无法实时更新的问题
    npm install 的时候出现 write access 导致不能成功安装的问题
    angular 的 @Input、@Output 的一个用法
    windows 安装 apache 服务以及添加 php 解析
    php 性能优化之opcache
    intellij 插件结构(文件结构以及概念层面上的结构)
    jetBrains 插件开发第一课-- 在主菜单栏新增一个菜单
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11257658.html
Copyright © 2020-2023  润新知