中国象棋

中国象棋

题目

【题目描述】

这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。

大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。

你也来和小可可一起锻炼一下思维吧!

【输入格式】

一行包含两个整数N,M,之间由一个空格隔开。

【输出格式】

总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。

【数据规模】

100%的数据中N和M均不超过100

50%的数据中N和M至少有一个数不超过8

30%的数据中N和M均不超过6

解析

动态规划题。

令f[i][j][k]表示前i行,放一个炮的有j列,放两个炮的有k列,边界为f[0][0][0]=1,,

则状态转移方程有以下几种:

1、不放:f[i][j][k]=f[i][j][k]+f[i-1][j][k];

2、放一个在零个的那列:f[i][j][k]=f[i][j][k]+f[i-1][j-1][k]*(m-j-k+1);

3、放一个在一个的那列:f[i][j][k]=f[i][j][k]+f[i-1][j+1][k-1]*(j+1);

4、分别放一个在一个的两列:f[i][j][k]=f[i][j][k]+f[i-1][j+2][k-2]*(j+1)*(j+2)/2;

5、分别放一个在零个的一列和一个的一列:f[i][j][k]=f[i][j][k]+f[i-1][j][k-1]*j*(m-j-k+1);

6、分别放一个在零个的两列:f[i][j][k]=f[i][j][k]+f[i-1][j-2][k]*(m-j-k+1)*(m-j-k+2)/2。

要注意各种情况的先决条件!最后的答案是所有f[n][j][k]的总和。记得开long long!!!

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
const int mod=9999973;
int n,m;
long long f[101][101][101],ans;
//f[i][j][k]表示前i行,放一个炮的有j列,放两个炮的有k列 
int main()
{
    memset(f,0,sizeof(f));
    cin>>n>>m;
    f[0][0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=0;j<=m;j++)
            for(int k=0;k<=m-j;k++)
            {
                f[i][j][k]=(f[i][j][k]+f[i-1][j][k])%mod;//不放
                if(j)//放一个在零个的那列
                    f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k]*(m-j-k+1))%mod;//(m-j-k+1)即原来零个的总列数 
                if(k)//放一个在一个的那列
                    f[i][j][k]=(f[i][j][k]+f[i-1][j+1][k-1]*(j+1))%mod;//(j+1)即原来一个的总列数 
                if(k>=2)//分别放一个在一个的两列
                    f[i][j][k]=(f[i][j][k]+f[i-1][j+2][k-2]*(j+1)*(j+2)/2)%mod;//(j+2)即原来有两列为一个的总列数 
                if(j&&k)//分别放一个在零个的一列和一个的一列
                    f[i][j][k]=(f[i][j][k]+f[i-1][j][k-1]*j*(m-j-k+1))%mod;
                if(j>=2)//分别放一个在零个的两列
                    f[i][j][k]=(f[i][j][k]+f[i-1][j-2][k]*(m-j-k+1)*(m-j-k+2)/2)%mod; 
            }
    for(int j=0;j<=m;j++)
        for(int k=0;k<=m-j;k++)
            ans=(ans+f[n][j][k])%mod;//累加答案     
    cout<<ans;
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/I-Love-You-520/p/11187691.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微思象棋播放器是一个基于jQuery开发的简单迷你并且高效的在线中国象棋棋谱播放器,基于网络访问并且兼容IE 7.0 ,Firefox 3.0 ,Opera 9.6 ,Chrome 1.0 ,Safari 3.22 ,并对IE 6.0提供部分支持。微思象棋播放器完全基于JavaScript开发,与服务器环境无关。微思象棋播放器可以使广大棋友方便的交流中国象棋棋局。微思象棋播放器可以在您的CMS、博客、论坛等互联网平台上完美的嵌入运行,能够非常灵活简单的和您的系统实现完美的无缝衔接。 微思象棋播放器 1.2.0 更新日志: 1. 新增走子着法朗读功能 2. 新增走子音效音量控制功能 3. 新增微博分享自定义URL功能,默认分享当前网址 4. 新增直播间观众模式触发式刷新功能,适用于WebSocket等模式 5. 优化手机中的效果,走子动画更加流畅 6. 优化组件路径,程序可自动识别图片、默认PHP接口等路径 7. API接口新增驼峰法命名,旧接口名仍可以使用 8. 修正了变招列表中残留项目符号的问题 9. 修正了直播间直播员模式每次走棋发送多次POST的问题 主要特点: 主程序经 GZIP 压缩后仅24KB,体积小巧,加载速度快。基于强大的 jQuery 引擎开发,执行效率高。 只需一句“vschess.load("jQuery选择器");”,便可瞬间将对应的 DOM 元素转换成可交互的动态棋盘。 动态棋盘支持动画播放,完全重现对弈时的场景,使您有身临其境的感觉。 象棋棋谱支持中文、WXF纵线、ICCS三种格式,播放过程中可任意切换。 播放器与专业象棋软件保持高度兼容,可将任意局面方便的复制到专业象棋软件中进行分析。 程序提供了众多程序API,便于开发人员与播放器进行通讯交互,亦可控制播放器的状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值