CodeForces 479E E. Riding in a Lift
2016-02-26 19:00
441 查看
CodeForces 479E E. Riding in a Lift
题目
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 the lift. Floor number b has a secret lab, the entry is forbidden. However, you already are in the mood and decide to make k consecutive trips in the lift.Let us suppose that at the moment you are on the floor number x (initially, you were on floor a). For another trip between floors you choose some floor with number y (y ≠ x) and the lift travels to this floor. As you cannot visit floor b with the secret lab, you decided that the distance from the current floor x to the chosen y must be strictly less than the distance from the current floor x to floor b with the secret lab. Formally, it means that the following inequation must fulfill: |x - y| < |x - b|. After the lift successfully transports you to floor y, you write down number y in your notepad.
Your task is to find the number of distinct number sequences that you could have written in the notebook as the result of k trips in the lift. As the sought number of trips can be rather large, find the remainder after dividing the number by 1000000007 (109 + 7).
Input
The first line of the input contains four space-separated integers n, a, b, k (2 ≤ n ≤ 5000, 1 ≤ k ≤ 5000, 1 ≤ a, b ≤ n, a ≠ b).
Output
Print a single integer — the remainder after dividing the sought number of sequences by 1000000007 (109 + 7).
题意
一个楼有N层,你起始在A层,有个神秘实验室在B层。假设你在x层,你能走到y层,满足 |x - y| < |x - b|. 你不能走到B层或者留在原地。一共走K次问有多少种走法。解题思路
一个很简单的题,但是有一个关键点是每次需要更新一个区间,更新区间的操作用线段树让代码很大而且复杂度高,其实可以用前缀和的方法,当需要更新区间[l, r]时,只需要更新l和r+1处(分别+val和-val),这样求前缀和就是新的dp值,总复杂度为O(N^2).代码
#include<bits/stdc++.h> using namespace std; const int SIZE = 5005; const int MOD = 1000000007; int N, A, B, K; int dp[SIZE][SIZE]; void slv(int x, int l, int r, int d) { dp[x][l] += d; dp[x][l] %= MOD; dp[x][r] -= d; dp[x][r] = ( dp[x][r] + MOD ) % MOD; } int main() { scanf("%d %d %d %d", &N, &A, &B, &K); dp[0][A] = 1; for(int i = 0; i < K; i++) { for(int j = 1; j <= N; j++) { if(j == B) continue; int temp = abs(j - B) - 1; slv(i+1, max(j-temp, 1), j, dp[i][j]); slv(i+1, j+1, min(j+temp+1, N+1), dp[i][j]); } int cnt = 0; for(int j = 1; j <= N; j++) { cnt += dp[i+1][j]; cnt %= MOD; dp[i+1][j] = cnt; } } int res = 0; for(int i = 1; i <= N; i++) { res += dp[K][i]; res %= MOD; } printf("%d\n",res); return 0; }
相关文章推荐
- emordnilaPdilaV.125
- Erlang 程序设计 学习笔记(五) 顺序编程
- Linux系统轻量级监控工具monitorix和munin安装
- 08_android入门_android-async-http开源项目介绍及用法
- 安卓音乐播放器中歌词同步问题
- 60,000毫秒内对Linux的性能诊断效的方法
- Linux下网络性能测试Netperf工具介绍及安装
- set集合的应用及注意事项以及案例详解
- 60,000毫秒内对Linux的性能诊断效的方法
- centos7常用工具软件安装
- ant 用法2
- 问卷调查
- loadrunner参数化
- Linux性能监测:监测目的与工具介绍
- CodeForces 614 B. Gena's Code(水~)
- 寻路算法合集
- 泛泰A900 刷4.4专用中文TWRP2.7.1.1版 支持自己主动识别手机版本号(全球首创)
- centos下安装fio
- 用yum查询想安装的软件
- 用yum查询想安装的软件