CodeForces 479 E. Riding in a Lift

CodeForces 479 E. Riding in a Lift_第1张图片CodeForces 479 E. Riding in a Lift_第2张图片

题意:一共n层楼,开始在第a层楼,在楼层b不能去的情况下,往其他楼层跳跃,求总共有多少种跳跃的方法。

需要满足条件 |x-y| < |x-b|  才能从 x 楼  到  y 楼。

刚开始是用当前状态去推下一个状态,由于要对能跳到的区间都加上这层楼的值,就想到了线段树,复杂度O(k*n log2(n)) 写完果然超时了。

然后改成用前一个状态推现在的状态,就发现,只需要求区间和就行了,于是用S数组存前N项和,复杂度O(k*n) 。

用 C [ J ]存目前为止到以 第 J 层楼为终点的路径数量,S [ J ]存C[ J ] 的前J项和。

每个操作{

对于每个楼层,新的C[ J ] = 能到这层楼的所有楼的旧的C 的和(利用S来计算)。

然后更新S数组。

}

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#define M 1000000007LL
#define maxn 5010
using namespace std;
int n,a,b,k;
long long C[maxn];
long long S[maxn];
void Caculate_S(){
	S[0]=0LL;
	for(int i=1;i<=n;++i) S[i]=(S[i-1]+C[i])%M;
}
long long Query(int L,int R){
	if(L > R) return 0LL;
	long long ANS=S[R]-S[L-1];
	return ANS <0LL?ANS+M:ANS;
}
int main(void)
{
	while(cin>>n>>a>>b>>k){
		memset(C,0,sizeof(C));
		C[a]=1;Caculate_S();
		for(int i=0;i<k;++i){
			for(int j=1;j<b;++j)	C[j]=Query(1,j-1)+Query(j+1,(b+j-1)>>1);
			for(int j=b+1;j<=n;++j)	C[j]=Query(j+1,n)+Query((b+j+2)>>1,j-1);
			Caculate_S();
		}
		cout<<S[n]<<endl;
	}
return 0;
}

你可能感兴趣的:(CodeForces 479 E. Riding in a Lift)