• 洛谷P2051 [AHOI2009]中国象棋(dp)


    题面

    luogu

    题解

    (50pts:)显然是(3)进制状压(dp)

    (100pts:)

    一行一行地考虑

    (f[i][j][k])表示前(i)行,有(j)列放了一个,有(k)列放了两个的方案数

    转移很显然

    Code

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
    	x = 0; RG char c = getchar(); bool f = 0;
    	while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
    	while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
    	x = f ? -x : x;
    	return ;
    }
    template<class T> inline void write(T x) {
    	if (!x) {putchar(48);return ;}
    	if (x < 0) x = -x, putchar('-');
    	int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
    	for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    const int N = 110, Mod = 9999973;
    int n, m;
    int f[N][N][N];
    void pls(int &x, LL y) {
    	y %= Mod;
    	x += y;
    	if (x >= Mod) x -= Mod;
    }
    
    int C(int x) {//C(x, 2)
    	return x * (x - 1) / 2;
    }
    
    int main() {
    	read(n), read(m);
    	f[0][0][0] = 1;
    	for (int i = 0; i < n; i++)//主动转移
    		for (int j = 0; j <= m; j++)
    			for (int k = 0; k + j <= m; k++)
    				if (f[i][j][k]) {
    					pls(f[i + 1][j][k], f[i][j][k]);
    					if (m - k - j) pls(f[i + 1][j + 1][k], 1ll * f[i][j][k] * (m - k - j));
    					if (j) pls(f[i + 1][j - 1][k + 1], 1ll * f[i][j][k] * j);
    					if (m - k - j > 1) pls(f[i + 1][j + 2][k], 1ll * f[i][j][k] * C(m - k - j));
    					if (j > 1) pls(f[i + 1][j - 2][k + 2], 1ll * f[i][j][k] * C(j));
    					if (m - k - j && j) pls(f[i + 1][j][k + 1], 1ll * f[i][j][k] * j * (m - k - j));
    				}
    	int ans = 0;
    	for (int j = 0; j <= m; j++)
    		for (int k = 0; k + j <= m; k++)
    			pls(ans, f[n][j][k]);
    	printf("%d
    ", ans);
    	return 0;
    }
    
    
  • 相关阅读:
    java 学习之JVM深入分析(一)
    选择排序算法实现十个1100的随机数的排序
    spring基础知识概述
    mybatis 总结一
    ACM之java判断回文数
    Spring mvc框架
    C#实现窗体最小化到状态栏,双击运行时又能正常显示窗体
    Android调用相机并将照片存储到SD卡上实现方法
    c#中如何让一个窗体在另一个旁边
    C#实现获取时间
  • 原文地址:https://www.cnblogs.com/zzy2005/p/10549410.html
Copyright © 2020-2023  润新知