首页 > 其他 > 详细

HDU-6787 Chess 线性dp 经典模型改

时间:2020-10-08 18:45:07      阅读:47      评论:0      收藏:0      [点我收藏+]

HDU-6787 Chess 线性dp 经典模型改

题意

现有一个\(n\)个格子的棋盘,你可以在棋盘上放置恰好\(m\)个传送带。

如果遇到传送带会立刻被送到传送位置。

传送位置满足:对于\(i\)号位,可以传送目标到\(j,j < i\)

1号位置不能放置传送带。

现一名玩家拿着一枚\(1,....11\)的骰子,每次会等概率的投出一个数字,如果当前位置在\(y\),那么棋子会跳到\(x + y\)。如果跳到棋盘外面游戏失败。

如果能够到达\(n\)且不被传送到别的地方玩家获胜。

问有多少种传送带的设置方法(摆放位置不同或者传送位置不同都视为不同的方案)每个格子最多放一个传送带。

问获胜的方案数。

分析

  • 不能在终点位置放置传送带。
  • 最多连续放置10个传送带
  • 如果没有传送带这个东西,此题就成为了经典的上楼梯模型。

\(dp[j][i][k]\)表示当前连续放置了\(j\)个传送带且最后一个传送带的位置在\(i\),总共放了\(k\)个传送带的方案数。

考虑到了当前位置

不放传送带

\[dp[0][i][k] = \sum_{j=0}^{j = min(k,10)}dp[j][i-1][k] \]

放传送带

\[dp[j][i][k] = dp[j-1][i-1][k-1] \times (i-1) \]

代码

int dp[11][1005][1005];
int n, m;

int main() {
    int T = readint();
    while (T--) {
        n = readint();
        m = readint();
        memset(dp, 0, sizeof dp);
        dp[0][1][0] = 1;
        for (int i = 2; i <= n; i++) {
            for (int k = 0; k <= m; k++) {
                for (int j = 0; j <= min(10,k); j++)
                    dp[0][i][k] += dp[j][i - 1][k], dp[0][i][k] %= MOD;
                if (i != n) {
                    for (int j = 1; j <= 10; j++)
                        if (k >= 1) dp[j][i][k] += (ll)dp[j - 1][i - 1][k - 1] * (i - 1) % MOD, dp[j][i][k] %= MOD;
                }
            }
        }
        Put(dp[0][n][m] ? dp[0][n][m] : -1);
        puts("");
    }
}

HDU-6787 Chess 线性dp 经典模型改

原文:https://www.cnblogs.com/hznumqf/p/13781218.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!