P2051 [AHOI2009]中国象棋

题意:

  给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况。合法放置的意思是棋子炮不会相互打到。

思路:

  这道题我们可以发现因为炮是隔一个棋子可以打出去,所以每一行每一列最多放置两个炮。

  这样子我们就可以试着压缩状态,记录前i行有几列是放一个棋子的,有几列是放两个棋子的,有几列是不放棋子的。

  即设dp[ i ][ j ] [ k ] 表示前 i 行,有 j 列是放一个棋子的,有k列是放两个棋子的,有 m - j - k列是不放棋子的。

  又由于每行最多可以放两个棋子,所以可以退出第i行和第i-1行的关系。

#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = ;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
}
/*-----------------------showtime----------------------*/ const int maxn = ;
ll dp[maxn][maxn][maxn];
ll c[maxn][maxn];
int n,m;
void init(){
c[][] = ;
for(int i=; i<=m; i++){
for(int j=; j<=i; j++){
if(j==) c[i][j] = ;
else if(j==i) c[i][j] = ;
else c[i][j] = (c[i-][j] + c[i-][j-])%mod;
}
}
}
int main(){
scanf("%d%d", &n, &m);
init();
dp[][][] = ;
for(int i=; i<=n; i++){
for(int j=; j<=m; j++){
for(int k=; k<=m-j; k++){ ll tmp = dp[i-][j][k];
if(k>) tmp = tmp + c[j+][] * dp[i-][j+][k-] % mod;
if(k>) tmp = tmp + c[j+][] * dp[i-][j+][k-] % mod;
if(j>) tmp = tmp + c[m-k-j+][] * dp[i-][j-][k] % mod;
if(j>) tmp = tmp + c[m-k-j+][] * dp[i-][j-][k] % mod;
if(k>) tmp = tmp + c[j][] * c[m-j-k+][] * dp[i-][j][k-]%mod;
tmp = tmp % mod;
dp[i][j][k] = tmp % mod;
}
}
}
ll ans = ;
for(int j=; j<=m; j++){
for(int k=; k<=m-j; k++){
ans = (ans + dp[n][j][k]) % mod;
}
}
printf("%lld\n", ans);
return ;
}

洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP的更多相关文章

  1. 洛谷 P2051 [AHOI2009]中国象棋 解题报告

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

  2. [洛谷P2051] [AHOI2009]中国象棋

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

  3. 洛谷 P2051 [AHOI2009]中国象棋

    题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...

  4. 洛谷P2051 [AHOI2009] 中国象棋(状压dp)

    题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...

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

    题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...

  6. [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...

  7. BZOJ1801或洛谷2051 [AHOI2009]中国象棋

    BZOJ原题链接 洛谷原题链接 这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能. 注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态. 设\(f[i][j ...

  8. 洛谷.2051.[AHOI2009]中国象棋(DP)

    题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...

  9. 洛谷2051 [AHOI2009]中国象棋

    题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...

随机推荐

  1. C# sql 批量插入数据库的语句

    //执行DataTable数据导入 public static int UpdateDt(string strConn, DataTable dt) { try { string tablaName ...

  2. 【JDK】JDK源码分析-Collection

    Java 集合框架(Java Collections Framework, JCF)包含很多平时开发中的常用类,例如 List.Set.ArrayList.HashMap.HashSet 等,因此打算 ...

  3. Nginx安装(详细版本)

    Nginx安装文档 前言: 最近,系统部署人员那边,让我们给写一个傻瓜式的Nginx安装过程.所以就有了这个文档,本着独乐乐不如众乐乐,就分享一下.我觉得对入门小白来说,有图,乃至运行过程图,是很重要 ...

  4. jplayer

    简介 jplayer是个用JavaScript写的完全免费和开源的媒体库(media library).作为jQuery插件的一员,使用jPlayer可以在你的网页上轻松加入跨平台的音乐和视频 使用方 ...

  5. .netcore持续集成测试篇之开篇简介及Xunit基本使用

    系列目录 为了支持跨平台,微软为.net平台提供了.net core test sdk,这样第三方测试框架诸如Nunit,Xunit等只需要按照sdk提供的api规范进行开发便可以被dotnet cl ...

  6. Linux系统关机与重新引导流程简介

    引言 在<Linux启动之旅>中,我们了解了Linux的启动过程,下面我们一同来学习Linux关机与重新引导流程. 不同于桌面系统,作为服务器,我们较少对Linux系统进行系统重启,但在以 ...

  7. PDF.js 详情解说

    pdf.js资源下载 点我下载 自定义默认加载的pdf资源 在web/view.js中我们可以通过DEFAULT_URL设置默认加载的pdf.通过上面代码我们也可以看出来可以通过后缀名来指定加载的pd ...

  8. wwww

    public class MainActivity extends AppCompatActivity implements XListView.IXListViewListener{ ; priva ...

  9. 【POJ - 3259】Wormholes(最短路 Floyd算法)

    Wormholes 题目描述 教学楼里有很多教室,这些教室由双向走廊连接.另外,还存在一些单向的秘密通道,通过它们可以回到过去.现在有 N (1 ≤ N ≤ 500) 个教室,编号 1..N, M ( ...

  10. go 学习笔记之数组还是切片都没什么不一样

    上篇文章中详细介绍了 Go 的基础语言,指出了 Go 和其他主流的编程语言的差异性,比较侧重于语法细节,相信只要稍加记忆就能轻松从已有的编程语言切换到 Go 语言的编程习惯中,尽管这种切换可能并不是特 ...