题意:给你一个n层楼的电梯,起始楼层为a,有一个楼层b永远都不能访问。假设你现在所在的楼层为 x ,目标楼层为y,y必须满足条件|x-y| < |x -b|
解题思路:时间复杂度是k×nxn,但是我们知道每次更新先把它存起来,然后到下一层再直接更新就行了,这里就需要用到前缀和。还要注意 mod 数加负数。
解题代码:
1 // File Name: 479e.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月08日 星期日 21时37分17秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 #define maxn 5005 28 #define M 1000000007 29 LL dp[maxn]; 30 LL tmp[maxn]; 31 int main(){ 32 int n,a,b,k; 33 scanf("%d %d %d %d",&n,&a,&b,&k); 34 dp[a] = 1; 35 for(int i = 1;i <= k ;i ++) 36 { 37 memset(tmp,0,sizeof(tmp)); 38 for(int j = 1;j <= n ;j ++) 39 { 40 if(j == b ) 41 continue; 42 int dis = abs(j-b)-1; 43 int l = max(j-dis,1); 44 int r = min(n,j+dis); 45 tmp[l] = (tmp[l]+dp[j])%M; 46 tmp[j] = (tmp[j]-dp[j])%M; 47 tmp[j+1] =(tmp[j+1]+dp[j])%M; 48 tmp[r+1] =(tmp[r+1]-dp[j])%M; 49 } 50 for(int j = 1;j <= n;j ++) 51 { 52 tmp[j] = (tmp[j-1] +M + tmp[j])%M; 53 } 54 for(int j= 1;j <= n;j ++) 55 dp[j] = tmp[j]; 56 dp[b] = 0; 57 } 58 LL sum =0 ; 59 for(int i = 1;i <= n;i ++) 60 { 61 sum = (sum + dp[i]) % M; 62 //printf("%I64d ",dp[i]); 63 } 64 printf("%I64d\n",sum); 65 return 0; 66 }
时间: 2024-10-12 18:10:28