zoukankan      html  css  js  c++  java
  • 洛谷 P2051 [AHOI2009]中国象棋

    这道题主要是状态很难想到
    首先可以看出每行每列不能超过2个棋子
    也就是说有0, 1, 2三种状态

    所以可以一行一行来处理
    那就用f[i][j][k]表示前i行,有j列放了一个棋子,有k列放了2个棋子的方案数
    放了0个棋子的列数是r=m-j-kr=m-j-k
    那么这个时候状态转移方程就非常好写了。
    对于当前这一行可以不放,放一个,放两个棋子
    0表示没有棋子的列,1表示有1个棋子的列。
    那么有几种情况

    不放
    放一个在0
    放一个在1
    放两个都在0
    放两个一个0一个1
    放两个在1

    放两个一个0一个1为例
    方程为f[i+1][j][k+1] = (f[i+1][j][k+1] +f[i][j][k] * r * j)
    这里用刷表法,比填表法方便非常多,但是要注意有些状态是不存在的(比如kj都等于m
    所以一开始要判断之前有没有刷到过这个状态

    现在解释一个这个方程
    现在是第i行,要填i+1行
    放一个在0的话,就有一个0变成1
    所以j要加1
    放一个在1的话,就有一个1变成2
    所以j要减1,k要加1
    这里0的列数不用管,因为推出j和k就可以知道0的列数了(m-j-k)
    所以j加1又减1,所以不变,而k+1
    所以是f[i+1][j][k+1]
    那么放一个在0一个在1的方法显然是0的列数乘上1的列数
    所以就是 f[i][j][k] * r * j

    最后就是把最后一行的所有情况加起来就是答案
    注意可以用define来简化代码

    #include<cstdio>
    #include<algorithm>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    #define _for(i, a, b) for(int i = (a); i <= (b); i++)
    #define cal(a, b) a = (a + b) % MOD
    using namespace std;
    
    const int MOD = 9999973;
    const int MAXN = 112;
    long long f[MAXN][MAXN][MAXN], n, m, ans;
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	f[0][0][0] = 1;
    	REP(i, 0, n)
    		_for(j, 0, m)
    			for(int k = 0; k + j <= m; k++)
    			{
    				if(!f[i][j][k]) continue;
    				int r = m - j - k;
    				cal(f[i+1][j][k], f[i][j][k]);
    				if(r >= 1) cal(f[i+1][j+1][k], f[i][j][k] * r);
    				if(j >= 1) cal(f[i+1][j-1][k+1], f[i][j][k] * j);
    				if(r >= 2) cal(f[i+1][j+2][k], f[i][j][k] * (r * (r - 1) / 2));
    				if(r >= 1 && j >= 1) cal(f[i+1][j][k+1], f[i][j][k] * r * j);
    				if(j >= 2) cal(f[i+1][j-2][k+2], f[i][j][k] * (j * (j - 1) / 2));
    			}
    	
    	_for(j, 0, m)
    		for(int k = 0; k + j <= m; k++)
    			cal(ans, f[n][j][k]);
    	printf("%lld
    ", ans);
    	
    	return 0;
    }


     

  • 相关阅读:
    C#音频截取与原文匹配2:使用ffmpeg处理音频文件
    C#音频截取与原文匹配
    Redis报错: StackExchange.Redis.RedisServerException: Endpoint 39.105.22.111:7200 serving hashslot 12448 is not reachable at this point of time.
    kafka单机安装部署
    zookeeper部署
    mysql-5.7.15编译安装
    centos7安装sqlserver
    redisearch模块安装
    yum安装软件后保留rpm包
    shell读取配置文件
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819365.html
Copyright © 2011-2022 走看看