zoukankan      html  css  js  c++  java
  • 2018.11.03-dtoj-3130-流浪者(rover)

    题目描述:

    有一位流浪者正在一个n*m的网格图上流浪。初始时流浪者拥有S点体力值。
    流浪者会从(1,1)走向(n,m),并且他只会向下走((x,y)→(x+1,y))或是往右走((x,y)→(x,y+1)),在所有可行的路线中他会随机选择一条。
    网络图中还有K个障碍点。若流浪者当前体力值为S,则他经过一个障碍点后体力值会变为⌈S/2⌉(上取整)。现
    在请你求出,流浪者到达(n,m)时他体力值的期望是多少。
    若答案为ab,则你输出ab在模109+7意义下的值即可。

    输入:

    第一行四个整数n,m,K,S, 意义见题目描述。
    接下来K行每行两个整数Xi,Yi,表示一个障碍点,保证一个障碍点不会出现多次。起点与终点可能也会是障碍点。

    输出:

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

    数据范围:

    30%的数据:n,m≤10
    50%的数据:n,m≤1000
    1000%的数据:1≤n,m≤105,0≤K≤min(n*m,2000),1≤S≤106

    算法标签:期望DP

    式子题,公式太难打了,仅附代码

    以下代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=1e5+5,p=1e9+7;
    LL jc[N<<1],ny[N<<1],ans;
    struct node{int x,y;}pi[2005];
    int n,m,k,tmp,num,s,f[2005][25];
    il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;}
    bool cmp(node t1,node t2){return (t1.x<t2.x||(t1.x==t2.x)&&t1.y<t2.y);}
    il LL ksm(LL a,int y){LL b=1;while(y){if(y&1)b=b*a%p;a=a*a%p;y>>=1;}return b;}
    il LL C(int n,int m){return jc[n]*ny[m]%p*ny[n-m]%p;}
    il LL way(int i,int j){
        int x=pi[j].x-pi[i].x,y=pi[j].y-pi[i].y;
        return C(x+y,x);
    }
    int main()
    {
        n=read();m=read();k=read();tmp=read();s=tmp;
        for(int i=1;i<=k;i++)pi[i].x=read(),pi[i].y=read();
        sort(pi+1,pi+1+k,cmp);pi[++k].x=n;pi[k].y=m;int kk=n+m;
        jc[0]=1;for(int i=1;i<=kk;i++)jc[i]=jc[i-1]*(LL)i%p;
        ny[kk]=ksm(jc[kk],p-2);for(int i=kk;i;i--)ny[i-1]=ny[i]*(LL)i%p;
        num=0;/*tmp=(tmp+1)>>1;*/while(tmp>1){num++;tmp=(tmp+1)>>1;}
        for(int i=1;i<=k;i++){
            for(int j=0;j<=num;j++){
                f[i][j]=C(pi[i].x+pi[i].y-2,pi[i].x-1);
                for(int kk=1;kk<i;kk++){
                    if(pi[kk].y>pi[i].y)continue;
                    f[i][j]=((f[i][j]-f[kk][j]*way(kk,i)%p)%p+p)%p;
                }
                for(int kk=1;kk<j;kk++){
                    f[i][j]=((f[i][j]-f[i][kk])%p+p)%p;
                }
            }
    //      f[i][num]=C(pi[i].x+pi[i].y-2,pi[i].x-1);
    //      for(int j=num;j>=1;j--)f[i][j]=((f[i][j]-f[i][j-1])%p+p)%p;printf("%d ",s);
        }
        for(int i=1;i<=num;i++){
            ans=(ans+(LL)s*f[k][i]%p)%p;s=(s+1)>>1;
        }
        LL sum=C(n+m-2,n-1);
        for(int i=1;i<=num;i++)sum=(sum-f[k][i]+p)%p;
        ans=(ans+sum)%p;
        ans=ans*ksm(C(n+m-2,n-1),p-2)%p;
        printf("%lld
    ",ans);
      return 0;
    }
    View Code
  • 相关阅读:
    FindBugs详解
    Java杂项
    Ubuntu 16.04安装DB2 Express C v11.1
    h5搜索功能
    与安卓交互的上传图片 与 上传语音、视频
    获取后台轮播图图片,让其自动播放
    点赞和关注功能
    split、replace、indexof、substr 用法 (获取后台富文本框内容,截取图片)
    ttyu平台进页面获取阅读量
    图片放大预览功能
  • 原文地址:https://www.cnblogs.com/Jessie-/p/9901359.html
Copyright © 2011-2022 走看看