码迷,mamicode.com
首页 > 其他好文 > 详细

繁华模拟赛 Vicent坐电梯

时间:2016-09-25 00:43:37      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

技术分享


/*
n<=5000
­这样就不能用O(n)的转移了,而是要用O(1)
的转移。
­注意我们每次的转移都来自一个连续的区间,
而且我们是求和
­区间求和?
­前缀和!
­sum[step][i]表示f[step][1~i]的和
­还是以B下侧为例
­ f[step][i]=sum[step-1][i-1]+sum[step-1][k]-sum[step-1][i]

*/
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int MAXN = 6000; const int MOD = 1000000007; int f[MAXN][MAXN] = {{0}}; int n, a, b, k; inline int getnum() { char c; int ans = 0; bool flag = false; while ((c = getchar()) == || c == \r || c == \n); if (c == -) flag = true; else ans = c - 0; while ((c = getchar()) >= 0 && c <= 9) ans = ans * 10 + c - 0; return ans * (flag ? -1 : 1); } inline void add(int &a, int b) { ll tmp = (ll)a + b; if (tmp >= MOD) a = (int)(tmp - MOD); else if (tmp < 0) a = (int)(tmp + MOD); else a = (int)tmp; } int main() { freopen("lift.in", "r", stdin); freopen("lift.out", "w", stdout); n = getnum(); a = getnum(); b = getnum(); k = getnum(); if (fabs(a - b) - 1 == 0) { printf("0\n"); return 0; } for (int i = a; i <= n; i++) f[0][i] = 1; for (int step = 1; step <= k; step++) for (int i = 1; i <= n; i++) if (i == b) f[step][i] = f[step][i - 1]; else { f[step][i] = f[step][i - 1]; if (i < b) { int x = (b + i) / 2; if ((b + i) % 2 == 0) x--; add(f[step][i], f[step - 1][x]); add(f[step][i], -f[step - 1][i]); add(f[step][i], f[step - 1][i - 1]); } else { int x = (b + i) / 2; add(f[step][i], f[step - 1][n]); add(f[step][i], -f[step - 1][x]); add(f[step][i], -f[step - 1][i]); add(f[step][i], f[step - 1][i - 1]); } } printf("%d\n", f[k][n]); }

 

繁华模拟赛 Vicent坐电梯

标签:

原文地址:http://www.cnblogs.com/hyfer/p/5904469.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!