zoukankan      html  css  js  c++  java
  • 【Foreign】Research Rover [DP]

    Research Rover

    Time Limit: 25 Sec  Memory Limit: 256 MB

    Description

      

    Input

      

    Output

      仅一行一个整数表示答案。

    Sample Input

      3 3 2 11
      2 1
      2 3

    Sample Output

      333333342

      

    HINT

      

    Main idea

      从(1,1)走到(n,m),每次可以向右或向下走一步,有K个特殊点,初始有一个权S,每经过一个特殊点S=(S+1)/2,询问到(n,m)的S的期望。

    Solution

      我们显然想到了DP,研究一下题目,发现可以按照到达目标之后S的值分类,显然S的取值只和经过特殊点的个数相关。并且由于每经过一个特殊点,S的值就会/2,那么显然只有log2(S)种取值,所以我们可以去考虑一个O(K^2log(S))的做法。

      首先,从起点走到终点的总方案数是:,我们可以将终点也当做特殊点,那么就可以令 f[i][j] 表示到了第 i 个目标点,经过 j 个目标点的方案数

      那么我们可以考虑容斥

      那么写成表达式也就是:

      其中:,计算方法显然和计算总方案一样,运用组合数。(组合数计算的时候求一下乘法逆元阶乘逆元即可)

      这样的话就可以算出到终点经过 i 个特殊点的方案、乘上对应的S的值、然后计算一下、再乘上总方案的乘法逆元就是答案了。

      效率就是O(k^2 * log(S)),就可以解决这道题啦。(≧▽≦)/

    Code

      1 #include<iostream>  
      2 #include<algorithm>  
      3 #include<cstdio>  
      4 #include<cstring>  
      5 #include<cstdlib>  
      6 #include<cmath>  
      7 using namespace std;
      8 typedef long long s64;
      9 const int ONE = 200005;
     10 const int INF = 214783640;
     11 const int MOD = 1e9+7;
     12 
     13 int Mod = MOD;
     14 int n,m,K,S;
     15 int f[ONE][30];
     16 int Jc[ONE],inv[ONE];
     17 int A[30],a_num;
     18 int Up;
     19 
     20 struct power
     21 {
     22         int x,y;
     23 }a[ONE];
     24 
     25 int cmp(const power &a,const power &b)
     26 {
     27         return a.x+a.y < b.x+b.y;
     28 }
     29 
     30 int get()
     31 { 
     32         int res,Q=1;    char c;
     33         while( (c=getchar())<48 || c>57)
     34         if(c=='-')Q=-1;
     35         if(Q) res=c-48; 
     36         while((c=getchar())>=48 && c<=57) 
     37         res=res*10+c-48; 
     38         return res*Q; 
     39 }
     40 
     41 namespace D
     42 {
     43         int Quickpow(int a,int b)
     44         {
     45             int res=1;
     46             while(b)
     47             {
     48                 if(b&1) res=(s64)res*a%MOD;
     49                 a=(s64)a*a%MOD;
     50                 b>>=1;
     51             }
     52             return res;
     53         }
     54     
     55         void Deal_Jc(int k)
     56         {
     57             Jc[0]=1;
     58             for(int i=1;i<=k;i++) Jc[i] = (s64)Jc[i-1]*i%MOD;
     59         }
     60         
     61         void Deal_inv(int k)
     62         {
     63             inv[0]=1;    inv[k] = Quickpow(Jc[k],MOD-2);
     64             for(int i=k-1;i>=1;i--) inv[i] = (s64)inv[i+1]*(i+1)%MOD;
     65         }
     66         
     67         void pre(int k)
     68         {
     69             Deal_Jc(k);    Deal_inv(k);
     70         }
     71 }
     72 int C(int n,int m)
     73 {
     74         return (s64)Jc[n]*inv[m]%MOD*inv[n-m]%MOD; 
     75 }
     76  
     77 int ways(int i,int j)
     78 {
     79         return C(a[j].x+a[j].y-a[i].x-a[i].y, a[j].x-a[i].x);
     80 }
     81 
     82 void Moit(int &a)
     83 {
     84         if(a<0) a+=MOD;
     85         if(a>MOD) a-=MOD;
     86 }
     87 
     88 int main()
     89 {
     90         n=get();    m=get();    K=get();    S=get();
     91             
     92         A[0]=S;    for(a_num=1;a_num<=24;a_num++) S=(S+1)/2, A[a_num]=S;
     93         D::pre(n+m);
     94         
     95            for(int i=1;i<=K;i++)
     96         {
     97             a[i].x=get();    a[i].y=get();
     98         }
     99         a[++K].x = n;    a[K].y = m;
    100         sort(a+1,a+K+1,cmp);
    101         
    102         for(int i=1;i<=K;i++)
    103         {
    104             for(int j=0;j<a_num;j++)
    105             {
    106                 f[i][j] = C(a[i].x+a[i].y-2,a[i].x-1);
    107                 for(int k=1;k<=i-1;k++)
    108                 {
    109                     if(a[k].x <= a[i].x && a[k].y <= a[i].y)
    110                     f[i][j] -= (s64)f[k][j] * ways(k,i) % MOD,
    111                     Moit(f[i][j]);
    112                 }
    113                 
    114                 for(int k=0;k<=j-1;k++)
    115                     f[i][j] -= f[i][k], Moit(f[i][j]);
    116             }
    117         }
    118         
    119         int All = C(n+m-2,n-1);
    120         
    121         for(int i=0;i<a_num;i++)
    122         {
    123             Up = (Up + (s64)f[K][i]*A[i]) % MOD;
    124             All -= f[K][i]; Moit(All);
    125         }
    126         
    127         Up = Up + All;    Moit(Up);
    128         
    129         printf("%d",(s64)Up * D::Quickpow(C(n+m-2,n-1),MOD-2) % MOD);
    130 }
    View Code

     

  • 相关阅读:
    js Map的使用
    javascript的Map使用
    解决vue视图不渲染
    SVN提示is already locked 解决办法
    AS报:Manifest merger failed with multiple errors, see logs
    使用Hbuilder手机debug
    在Html页面中调用ajax代码
    JAVA跨域CORS
    vue2.0的初始化
    jquery的$(selector).each(function(index,element))和$.each(dataresource,function(index,element))的区别
  • 原文地址:https://www.cnblogs.com/BearChild/p/6512109.html
Copyright © 2011-2022 走看看