Codeforces 479E Riding in a Lift

Posted GFY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",f[K%2][pos]);
    return 0;
}

 

 

 

以上是关于Codeforces 479E Riding in a Lift的主要内容,如果未能解决你的问题,请参考以下文章

CF479E Riding in a Lift (dp)

USACO 3.3 Riding the Fences

ural 2022 Riding a Toad

Little Red Riding Hood

luogu P2731 骑马修栅栏 Riding the Fences

P2731 骑马修栅栏 Riding the Fences