zoukankan      html  css  js  c++  java
  • HDUChess 递推

    这题一开始想用状态压缩DP解,后来发现状态开不下...还是没有很好的理解啊。

    这里将棋盘看做是两个正方形,由于只能够走对角线,所以两个正方形可以看做是无关的,因此我们只要求出每个正方形走相应步数的方案。对于k不而言,在两个正方形里面就有(1, k-1), (2, k-2)...例如这样的分法,必须保证所有的分法都是合法的。现在问题就在于如何去求一个N*N的矩阵能放置一些棋子,这些棋子要求上下左右不能够在同行同列的方案数。其实就是一个简单的递推而已,我们定义dp[i][j]表示到第i行放置j个方案数,那么dp[i][j] = dp[i-1][j] + dp[i-1][j-1]*(n-j+1),其实也就是一个放与不放的选择。最后组合就能够得到答案了。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define MAXN 55
    #define MOD 100007
    using namespace std;
    
    int N, M, dp[2][MAXN][MAXN];
    
    // dp[.][i][j] 表示到第i行放置了j个方案数 dp[,][i][j] = C(j, i) * A(j, N)
    // C(j, i) * A(j , N) = C(j, i-1) * A(j, N) + C(j-1, i-1) * A(j, N) = C(j, i-1) * A(j, N) + (N-j+1) * C(j-1, i-1) * A(j-1, N)
    // 上式也即 dp[.][i][j] = dp[.][i-1][j] + dp[.][i-1][j-1] * (N - j + 1) 
    
    void DP(int f, int n) {
        dp[f][0][0] = 1;
        for (int i = 1; i <= n; ++i) {
            dp[f][i][0] = 1;
            for (int j = 1; j <= i; ++j) {
                dp[f][i][j] = dp[f][i-1][j]; // 第i行放或者是不放
                dp[f][i][j] += dp[f][i-1][j-1] * (n - j + 1);
                dp[f][i][j] %= MOD;
            }
        }
    }
    
    int main() {
        int a, b, ret;
        while (scanf("%d %d", &N, &M) == 2) {
            if (M > N) {
                puts("0");
                continue;
            }
            ret = 0;
            a = (N + 1) >> 1;
            b = (N - 1) >> 1;
            DP(0, a), DP(1, b);
            for (int i = 0; i <= M; ++i) {
                if (i > a || (M-i) > b) continue;
                ret += (long long)dp[0][a][i] * dp[1][b][M-i] % MOD;
                ret %= MOD;
            }
            printf("%d\n", ret);
        }
        return 0;    
    }
  • 相关阅读:
    我的大菠萝 – 2,控件及数据绑定
    我的大菠萝 – 1,大框架的搭建
    企业培训·在线教育产品出来后为什么团队元老选择离职
    ET中热更(ILRuntime)使用过程中,需要做的适配器,比如Linq排序
    ET–异步协程使用–TimerComponent篇
    Windows Phone开发之”给我好评“
    博客园,我开始自己的随笔啦
    转换服务的端口号
    多进程模块multiprocessing的使用
    python中协程的使用示例
  • 原文地址:https://www.cnblogs.com/Lyush/p/2643360.html
Copyright © 2011-2022 走看看