• Codeforces 479E Riding in a Lift


    http://codeforces.com/problemset/problem/432/D

    题目大意:

    给出一栋n层的楼,初始在a层,b层不能去,每次走的距离必须小于当前位置到b的距离,问用电梯来回乱跑得到的序列有多少种。

    思路:发现在a的这一侧永远不会到b的另一侧去,因此我们拆开来,只保留a所在的这边,dp:

    f[i][j]=Σf[i-1][j] (1<=j<=i+i-1)

    然后我们记录前缀和,一边算出sum[1,i-1],另一边用两个指针l,r,每次r移动2,l移动1,算出sum[l,r]

    PS:之前用l和r还一边走一边修改真是太傻比了

     

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #define ll long long
    const ll Mod=1000000007;
    ll f[2][10005],sum[200005];
    int n,a,b,K,len,pos;
    int read(){
        int t=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
        while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
        return t*f;
    }
    ll query(int l,int r){
        if (r>len) r=len;
        return (((sum[r]-sum[l-1])%Mod)+Mod)%Mod;
    }
    int main(){
        n=read();a=read();b=read();K=read();
        if (a<b) len=b-1,pos=b-a;else len=n-b,pos=a-b;
        for (int i=1;i<=len;i++)
         f[0][i]=1;
        for (int i=1;i<=K;i++){
         ll cnt=0;
         for (int j=0;j<=len;j++)
          f[i%2][j]=0;
         sum[0]=0;
         for (int j=1;j<=len;j++)
          sum[j]=(sum[j-1]+f[(i-1)%2][j])%Mod; 
         for (int j=1;j<=len;j++){
          f[i%2][j]=(f[i%2][j]+cnt)%Mod;
          cnt=(cnt+f[(i-1)%2][j])%Mod;
         }
         cnt=0;
         int r=len+len-1,l=len+1;
         for (int j=len;j>=1;j--){
            f[i%2][j]=(f[i%2][j]+query(l,r))%Mod;
            r-=2;
            l--;
         }  
        }
        printf("%I64d
    ",f[K%2][pos]);
        return 0;
    }

     

     

  • 相关阅读:
    Cisco 交换机配置的基本命令
    Mysql读写分离方案-Amoeba环境部署记录
    centos7下部署zabbix3.4+grafana
    Docker
    Linux 安装源码软件
    mysql 日志
    mysql导出导入数据
    mysql 数据库的备份和还原
    Mysql 数据库管理
    英语单词
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5631320.html
Copyright © 2020-2023  润新知