zoukankan      html  css  js  c++  java
  • 繁华模拟赛 Vicent坐电梯


    /*
    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 == ' ' || c == ' '); 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 "); 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 ", f[k][n]); }
  • 相关阅读:
    两种方法生成随机字符串
    cmd命令总结
    NOI前乱写
    多校模拟9
    字符串 口胡
    HEOI2020游记
    省选模拟104
    省选模拟103
    省选模拟102
    省选模拟101
  • 原文地址:https://www.cnblogs.com/hyfer/p/5904469.html
Copyright © 2011-2022 走看看