博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
炮(棋盘DP)
阅读量:6576 次
发布时间:2019-06-24

本文共 1294 字,大约阅读时间需要 4 分钟。

 

 

  一直以为自己写的就是状态压缩,结果写完才知道是个棋盘dp

  首先看一下题目

  嗯,象棋 ,还是只有炮的象棋

  对于方案数有几种,我第一个考虑是dfs,但是超时稳稳的,所以果断放弃

  然后记得以前有过和这个题差不多的dp题

  所以思路开始转向DP

  经仔细思考后 将棋盘的状态压为三维

  dp[i][k][j];

  i:棋盘的第几行  k:前i行有几列放了一个炮棋  j:前i行有几列放了两个炮棋

  因为炮会隔棋打,所以一列或者一行最多存在两个炮棋

  所以

  dp方程有6个元素:

  1:不放炮棋,所以方程为 dp[i][k][j]+=dp[i-1][k][j];

  2:往一个没有炮棋的列放一个炮棋,方程为dp[i][j][k]+=dp[i-1][k-1][j]*(m-k-j+1);

  3:往一个有一个炮棋的列放一个炮棋,方程为dp[i][j][k]+=dp[i-1][k+1][j-1]*(k+1);

  4:往一个有一个炮棋的列放一个炮棋同时往一个没有炮棋的列放一个炮棋,方程为dp[i][j][k]+=dp[i-1][k][j-1]*(k)*(m-j-k+1)/2;

  5:往一个有一个炮棋的列放一个炮棋同时往一个有一个炮棋的列放一个炮棋,方程为dp[i][k][j]+=(k+2)*(k+1)/2*dp[i-1][k+2][j-2];

  6:往一个没有炮棋的列放一个炮棋同时往一个没有炮棋的列放一个炮棋,方程为dp[i][k][j]+=(m-j-k+2)*(m-j-k+1)/2*dp[i-1][k-2][j];

 

  好了,现在可以贴代码了

  

#include
#include
#define mod 999983using namespace std;int n,m;long long int dp[101][101][101],ans=0;int main(){ scanf("%d%d",&n,&m); dp[0][0][0]=1; for(int i=1;i<=n;i++) { for(int k=0;k<=m;k++) { for(int j=0;j<=m-k;j++) { dp[i][k][j]=dp[i-1][k][j]; if(k) dp[i][k][j]+=(m-k-j+1)*dp[i-1][k-1][j]%mod; if(j&&k
1) dp[i][k][j]+=(m-j-k+2)*(m-j-k+1)/2*dp[i-1][k-2][j]%mod; if(j>1&&k

 

转载于:https://www.cnblogs.com/IUUUUUUUskyyy/p/6022541.html

你可能感兴趣的文章
洛谷P2179 [NOI2012]骑行川藏(拉格朗日乘数法)
查看>>
FastCGI高级指南
查看>>
qemu -net tap配置上网
查看>>
358. Rearrange String k Distance Apart
查看>>
实践:VIM深入研究(20135301 && 20135337)
查看>>
MyCAT源码分析——分析环境部署
查看>>
网页录音并上传
查看>>
数组Array,集合List与字符串String,整形int的get类方法。
查看>>
服务器大量的fin_wait1 状态长时间存在原因分析
查看>>
PHP 笔记——Web页面交互
查看>>
(How to)使用IE9的F12开发人员工具分析模拟登陆网站(百度首页)的内部逻辑过程
查看>>
PHP的那些坑
查看>>
详解web容器 - Jetty与Tomcat孰强孰弱
查看>>
hdu1219
查看>>
Day5_协程函数_面向过程
查看>>
Android屏幕旋转总结
查看>>
将博客搬至CSDN
查看>>
(转载)myeclipse项目名称重命名
查看>>
redis哨兵集群
查看>>
积性函数和狄利克雷卷积小结
查看>>