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

[题解] [AGC013D] Piling Up

时间:2020-01-16 10:52:06      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:string   www   坐标轴   for   ret   pac   str   pen   cst   

题面

题解

把操作放到坐标轴上, \(y\) 轴代表黑球个数, \(x\) 球代表操作次数

然后对应的操作就可以看作加上 \((1, 1)\)\((1, -1)\) 的两个向量

于是对应的操作序列就变为了一根折线

但是有可能会有重复的情况

我们只计算到达过 \(x\) 轴的那一根

并且这是肯定可以实现的

于是我们设 \(f[i][j][0 / 1]\) 代表前 \(i\) 次操作, 黑球还有 \(j\) 个, 没有 / 有经过 \(0\)

转移的话是这样的

假如说这次拿出了两个黑球

\(f[i - 1][j][1] \to f[i][j - 1][1] (j \geq 1)\) , \(f[i - 1][j][0] \to f[i][j - 1][0] (j \geq 2)\) , \(f[i - 1][j][0] \to f[i][j - 1][1] (j = 1)\)

拿了两个白球

\(f[i - 1][j][0 / 1] \to f[i][j + 1][0 / 1] (j < n)\)

这次拿了先黑再白

\(f[i - 1][j][1] \to f[i][j][1] (j \leq 1)\) , \(f[i - 1][j][0] \to f[i][j][0] (j \leq 2)\) , \(f[i - 1][j][0] \to f[i][j][1] (j = 1)\)

这次拿了先白再黑

\(f[i - 1][j][0 / 1] \to f[i][j][0 / 1] (j < n)\)

答案就是 \(\sum_{j = 0}^{n} f[m][j][1]\)

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
const int N = 3005;
const int mod = 1000000007; 
using namespace std;

int n, m, f[N][N][2], ans; 

template < typename T >
inline T read()
{
    T x = 0, w = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * w; 
}

int main()
{
    n = read <int> (), m = read <int> ();
    for(int i = 1; i <= n; i++)
        f[0][i][0] = 1;
    f[0][0][1] = 1;
    for(int i = 1; i <= m; i++)
        for(int j = 0; j <= n; j++)
        {
            if(!j)
            {
                f[i][j][1] = f[i - 1][j][1];
                if(j < n) f[i][j][1] = (1ll * f[i][j][1] + f[i - 1][j + 1][1] + f[i - 1][j + 1][0]) % mod; 
            }
            else if(j == 1)
            {
                if(j < n) f[i][j][0] = (f[i][j][0] + f[i - 1][j + 1][0] + f[i - 1][j][0]) % mod; 
                f[i][j][1] = (1ll * f[i - 1][j][1] + f[i - 1][j][0] + f[i - 1][j - 1][1]) % mod;
                if(j < n) f[i][j][1] = (1ll * f[i - 1][j + 1][1] + f[i][j][1] + f[i - 1][j][1]) % mod; 
            }
            else
            {
                f[i][j][0] = (1ll * f[i - 1][j][0] + f[i - 1][j - 1][0]) % mod; 
                f[i][j][1] = (1ll * f[i - 1][j][1] + f[i - 1][j - 1][1]) % mod;
                if(j < n)
                {
                    f[i][j][0] = (1ll * f[i][j][0] + f[i - 1][j][0] + f[i - 1][j + 1][0]) % mod;
                    f[i][j][1] = (1ll * f[i][j][1] + f[i - 1][j][1] + f[i - 1][j + 1][1]) % mod;
                }
            }
        }
    for(int i = 0; i <= n; i++)
        ans = (1ll * ans + f[m][i][1]) % mod; 
    printf("%d\n", ans); 
    return 0; 
}

在洛谷上蒯的第一篇题解的转移方程, 不想写了

[题解] [AGC013D] Piling Up

标签:string   www   坐标轴   for   ret   pac   str   pen   cst   

原文地址:https://www.cnblogs.com/ztlztl/p/12199639.html

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