zoukankan      html  css  js  c++  java
  • BZOJ 4005 [JLOI 2015] 骗我呢

    首先,我们可以得到:每一行的数都是互不相同的,所以每一行都会有且仅有一个在 $[0, m]$ 的数没有出现。

    我们可以考虑设 $Dp[i][j]$ 为处理完倒数 $i$ 行,倒数第 $i$ 行缺的数字是 $j$ 的方案数。

    那么就有:

    $$Dp[i][j] = sum_{k=max(0,j-1)}^{m}Dp[i - 1][k]$$

    自己画一画图就可以明白了,在这里就不解释了。毕竟 Gromah 太懒($rugrave{o}$)

    然后我们考虑把这个转移图画出来:

    然后就是求这个图中从右上到左下的路径条数嘛。(每次只能往左或者是往右下或者是往下)

    转化一下,实际上就是求这个东西:

    从 $(0,0)$ 到 $(n*2+m+1,m+1)$,每次可以 $x+1,y-1$ 或者 $x+1,y+1$,并且不穿过 $y=0$ 和 $y=m+1$ 这两条直线的路径条数。

    首先,全集是 ${n*2+m+1 choose m+1}$,

    然后我们算穿过 $y=0$ 的路径条数,既然穿过 $y=0$ 就必然经过 $y=-1$,于是我们让终点和 $y=m+2$ 这条直线沿着 $y=-1$ 翻转,

    然后就可以算出 $(0,0)$ 到翻转之后的终点的路径条数。

    于是还没完。还有那些先穿过 $y=0$ 再又穿过 $y=m+1$ 这条直线的路径我们要加回来。。。

    于是又把坐标系沿着翻转之后的 $y=m+2$ (此时应该是 $y=-m-4$ 了)再次翻转。再统计答案。。。

    直到方案为 $0$ 了为止。

    计算穿过 $y=m+1$ 的路径条数同理。。。

    我知道我语言表达能力及其低下,所以还是上代码好了。。。

     1 #include <cmath> 
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef long long LL;
     8 #define N 3000000
     9 #define Mod 1000000007
    10 
    11 int n, m, ans = 0;
    12 int Fac[N + 1], Inv[N + 1];
    13 
    14 inline int power(int u, int v)
    15 {
    16     int res = 1;
    17     for (; v; v >>= 1)
    18     {
    19         if (v & 1) res = (LL) res * u % Mod;
    20         u = (LL) u * u % Mod;
    21     }
    22     return res;
    23 }
    24 
    25 inline void Prepare()
    26 {
    27     Fac[0] = Inv[0] = 1;
    28     for (int i = 1; i <= N; i ++)
    29         Fac[i] = (LL) Fac[i - 1] * i % Mod;
    30     Inv[N] = power(Fac[N], Mod - 2);
    31     for (int i = N - 1; i ; i --)
    32         Inv[i] = (LL) Inv[i + 1] * (i + 1) % Mod;
    33 }
    34 
    35 inline int C(int u, int v)
    36 {
    37     if (u < 0 || v < 0 || u < v) return 0;
    38     return (LL) Fac[u] * Inv[v] % Mod * Inv[u - v] % Mod;
    39 }
    40 
    41 inline int T(int u, int v)
    42 {
    43     if (u < abs(v)) return 0;
    44     return C(u, u - abs(v) >> 1);
    45 }
    46 
    47 inline int Inc(int u, int v)
    48 {
    49     return u + v - (u + v >= Mod ? Mod : 0);
    50 }
    51 
    52 int main()
    53 {
    54     #ifndef ONLINE_JUDGE
    55         freopen("4005.in", "r", stdin);
    56         freopen("4005.out", "w", stdout);
    57     #endif
    58     
    59     Prepare();
    60     scanf("%d%d", &n, &m);
    61     int x = n * 2 + m + 1;
    62     ans = T(x, m + 1);
    63     
    64     for (int y = m + 1, y_1 = -1, y_2 = m + 2; x >= abs(y); )
    65     {
    66         y = 2 * y_1 - y;
    67         y_2 = 2 * y_1 - y_2;
    68         ans = Inc(ans, Mod - T(x, y));
    69         y = 2 * y_2 - y;
    70         y_1 = 2 * y_2 - y_1;
    71         ans = Inc(ans, T(x, y));
    72     }
    73     
    74     for (int y = m + 1, y_1 = m + 2, y_2 = -1; x >= abs(y); )
    75     {
    76         y = 2 * y_1 - y;
    77         y_2 = 2 * y_1 - y_2;
    78         ans = Inc(ans, Mod - T(x, y));
    79         y = 2 * y_2 - y;
    80         y_1 = 2 * y_2 - y_1;
    81         ans = Inc(ans, T(x, y));
    82     }
    83     
    84     printf("%d
    ", ans);
    85     
    86     #ifndef ONLINE_JUDGE
    87         fclose(stdin);
    88         fclose(stdout);
    89     #endif
    90     return 0;
    91 }
    4005_Gromah
  • 相关阅读:
    锦oa基础配置
    存储localStorage
    刷新token
    input框输入数量自动计算价格
    创建项目,登录校验
    config
    xiaota-main
    数据库的多表查询
    pygame应用---射击外星人游戏
    pygame以及matplotlib的安装
  • 原文地址:https://www.cnblogs.com/gromah/p/4464187.html
Copyright © 2011-2022 走看看