您的位置:首页 > 其它

codeforces Round #274(div2) E解题报告

2014-10-20 12:22 337 查看
E. Riding in a Lift

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

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).

Sample test(s)

input
5 2 4 1


output
2


input
5 2 4 2


output
2


input
5 3 4 1


output
0


Note

Two sequences p1, p2, ..., pk and q1, q2, ..., qk are distinct,
if there is such integer j (1 ≤ j ≤ k),
that pj ≠ qj.

Notes to the samples:

In the first sample after the first trip you are either on floor 1, or on floor 3,
because |1 - 2| < |2 - 4| and |3 - 2| < |2 - 4|.

In the second sample there are two possible sequences: (1, 2); (1, 3).
You cannot choose floor 3 for the first trip because in this case no floor can be the floor for the second trip.

In the third sample there are no sought sequences, because you cannot choose the floor for the first trip.

题目大意:

初始的层数为a,其中b为禁区,现在要求乘坐k次电梯的总方案数。其中每次乘坐电梯时,必须满足要求 |x-y| < |x-b|。

解法:

      首先明确一点,如若a < b,则无论如何都不可能乘坐到大于b的那一部分,反之亦然。

      采用动态规划策略,这里我们可以以i为乘坐了i次,j为哪一层电梯。f[i][j] = sum(f[i-1][m]) - f[i-1][j],这里的m为满足条件的上一个楼层(设上一个楼层为x |x-j| < |x-b| )。这里的时间复杂度为O(k*n*n);

      我们可以发现,m为一段连续区间,我们就可以用sum先累积起来,这里就直接简化为O(1),总的时间复杂度为O(k*n)。(PS: 注意m的边界)

      这里要求我们取模,由于运算过程中,我们可能会出现负数,所以,我们得采用(x+mo)%mo的方式,保证不会出现负数。

代码:

#include <cstdio>
#define N_max 5010#define mo 1000000007

int n, a, b, k, tmpl, tmpr, l, r;
int f[2][N_max], sum[N_max];

void init() {
scanf("%d%d%d%d", &n, &a, &b, &k);

f[0][a] = 1;
}

void solve() {
int now=0, pre=1;

for (int i = 1; i <= k; i++) {
now ^= 1;
pre ^= 1;

for (int j = 1; j <= n; j++)
sum[j] = (sum[j-1]+f[pre][j])%mo;

if (a < b)
for (int j = 1; j <= b-1; j++) {
tmpr = j+(b-j+1)/2-1;
f[now][j] = (sum[tmpr]+mo)%mo;
f[now][j] = (f[now][j]- f[pre][j] + mo)%mo;
}
else
for (int j = b+1; j <= n; j++) {
tmpl = j-(j-b+1)/2+1;
f[now][j] = (sum
- sum[tmpl-1]+mo)%mo;
f[now][j] = (f[now][j]- f[pre][j] + mo)%mo;
}
}

int ans=0;
for (int i = 1; i <= n; i++)
ans = (ans+f[now][i])%mo;
printf("%d\n", ans);
}

int main() {
init();
solve();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces acm dp