[CF479E] Riding in a Lift - dp
Description
一个楼有N层,由于你很无聊,你开始玩电梯。你的初始位置在A层,有个神秘实验室在B层,所以你的移动会受到如下限制:假设你在x层,你能走到的y层都要满足 |x - y| < |x - b|. 你不能走到B层或者留在原地。问一共走K次,有多少种走法。(n,k le 5000)
Solution
前缀和优化 dp
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, a, b, k;
int f[5005], s[5005];
const int mod = 1e9 + 7;
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> a >> b >> k;
s[a] = 1;
for (int i = 1; i <= k; i++)
{
for (int j = 1; j <= n; j++)
{
if (j < b)
f[max(1ll, 2 * j - b + 1)] += s[j];
if (j < b)
f[b] -= s[j];
if (j > b)
f[b + 1] += s[j];
if (j > b && 2 * j - b <= n)
f[2 * j - b] -= s[j];
}
for (int j = 1; j <= n; j++)
f[j] = (f[j] % mod + mod) % mod;
for (int j = 1; j <= n; j++)
f[j] += f[j - 1];
for (int j = 1; j <= n; j++)
f[j] -= s[j];
for (int j = 1; j <= n; j++)
f[j] = (f[j] % mod + mod) % mod;
for (int j = 0; j <= n; j++)
s[j] = f[j], f[j] = 0;
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans += s[i];
cout << ans % mod << endl;
}