CodeForces 479E Riding in a Lift

题意:给你一个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

CodeForces 479E Riding in a Lift的相关文章

Codeforces 479E Riding in a Lift(dp)

题目链接:Codeforces 479E Riding in a Lift 题目大意:有一栋高N层的楼,有个无聊的人在A层,他喜欢玩电梯,每次会做电梯到另外一层.但是这栋楼里有个秘 密实验室在B层,所以每次他移动的时候就有了一个限制,x为当前所在层,y为目标层,|x - y| < |x - b|.问说移动K次 后,有多少不同的路径. 解题思路:dp[i][j]表示在第i步到达j层有多少种不同的路径,dis = abs(j-B) - 1,那么在[j-dis,j+dis]这个范围都能被转 移,除了j

Codeforces 479E Riding in a Lift:前缀和/差分优化dp

题目链接:http://codeforces.com/problemset/problem/479/E 题意: 有一栋n层的房子. 还有一个无聊的人在玩电梯,每次玩电梯都会从某一层坐到另外一层. 他初始在a层,然后要玩k次电梯. 这栋楼里还有一个神秘实验室,在b层. 这让他每次坐电梯受到了限制: 当前在x层,然后要坐到y层,则必须满足|x-y|<|x-b| 问你共有多少种坐电梯的方案. 题解: 表示状态: dp[i][j] = numbers 表示当前在第i层,已经坐了j次电梯,此时的方案数.

Codeforces 480C Riding in a Lift dp

题目链接:点击打开链接 题意: 给定 n a b k 构造一个长度为k的序列. 使得序列中 对于任意两个相邻的数 | w[i-1] - w[i] | < | w[i] - b | 且第一个数 |a - w[1] | < | w[1] - b | 问: 有多少种不同的序列. 思路:dp 对于粗暴的dp复杂度是 n^3 我们可以用前缀和来优化掉一维的dp.. 反正是简单粗暴的题.具体看代码吧.. #include <cstdio> #include <iostream> #

CF 479E Riding in a Lift 前缀和 DP

输入 n a b k 有n层楼 起点在a层 b层是不能到达的 假设当前在x层 每一次可以到达y层 满足 |x-y| < |x-b| 求进行k次的不同方案数 dp[i][j]为第i次到达j层的方案数 dp[i][j] = sum(dp[i-1][k])  其中|k-j| < |k-b| 满足条件的k是连续的一段 用前缀和优化 #include <cstdio> #include <cstring> #include <cstdlib> using namesp

Codeforces Round #274 (Div. 2) E. Riding in a Lift(DP)

Imagine that you are in a building that has exactly n floors. You can move between the floors in a lift. Let's number the floors from bottom to top with integers from 1 to n. Now you're on the floor number a. You are very bored, so you want to take t

Codeforces Round #274 (Div. 2) E:Riding in a Lift DP + 前缀优化

题意: n,a,b,k(2?≤?n?≤?5000,1?≤?k?≤?5000,1?≤?a,?b?≤?n,a?≠?b).四个数.1到n的数,顺序排列,其实位置人在a位置而中心位置在b,人每次只能走一个点走动的距离必须小于|b?a|,人走k步之后停止,问人一共有多少种走法. 分析: 开始很容易想到一个深度优先搜索实现递归方法dfs(a, k)但k变为0就到达搜索底部,这样时间复杂度是O(nk)显然非常不好. 然后可以想到会有重算的情况,就可以加一个记忆优化把算过的(a,k)的二元组都保存下来.这样处理

Codeforces Round #274 Div.1 C Riding in a Lift --DP

题意:给定n个楼层,初始在a层,b层不可停留,每次选一个楼层x,当|x-now| < |x-b| 且 x != now 时可达(now表示当前位置),此时记录下x到序列中,走k步,最后问有多少种可能的数的序列. 解法: 定义:      dp[i][j] 表示第i步在j楼的不同序列的个数 转移方程: 当j<b时, 那么dp[i][j] += dp[i-1][0~(j与b的中点(以下))] 当j>b时, 那么dp[i][j] += dp[i-1][(j与b的中点(以下))~n] 由于dp[

CF R274 Div2 E Riding in a Lift DP

先预处理出能到当前点的区间,然后通过前缀和求得当前值即可. #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <climits> #include <iostream> #include &

CodeForces 274E. Riding in a LiftDp

题意:从a 开始不能到达b,要坐k次电梯的满足条件 :|x - y| < |x - b|. x是当前位置,y是目标位置 的方案数. 每次转移处理个前缀和,然后每次满足条件的和的范围是 :1到 (y+b-1) /2 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostrea