洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
题意:
给定一个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的更多相关文章
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷P2051 [AHOI2009] 中国象棋(状压dp)
题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...
- 洛谷P2051 [AHOI2009]中国象棋(dp)
题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...
- [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)
题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...
- BZOJ1801或洛谷2051 [AHOI2009]中国象棋
BZOJ原题链接 洛谷原题链接 这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能. 注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态. 设\(f[i][j ...
- 洛谷.2051.[AHOI2009]中国象棋(DP)
题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...
- 洛谷2051 [AHOI2009]中国象棋
题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...
随机推荐
- 微信小程序的尺寸单位rpx介绍
rpx单位是微信小程序中css的尺寸单位,rpx可以根据屏幕宽度进行自适应. 规定屏幕宽为750rpx.如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375 ...
- XSS危害——session劫持(转载)
在跨站脚本攻击XSS中简单介绍了XSS的原理及一个利用XSS盗取存在cookie中用户名和密码的小例子,有些同学看了后会说这有什么大不了的,哪里有人会明文往cookie里存用户名和密码.今天我们就介绍 ...
- Asp.Net MVC 高级特性(附带源码剖析)
1. 程序入口(MvcHandler,RouteHandler,HttpModule) 2.异步类包(静态类AsyncResultWrapper),开启整个MVC异步循环 3.Aggregate递归链 ...
- sentos中bonding(网卡绑定技术)1
一.GRUB添加kernel参数 1.# vim /etc/sysconfig/grubGRUB_CMDLINE_LINUX="...... net.ifnames=0" ...
- JAVA开始(基础篇)
数据类型 Boolean 1位Byte 1个字节(8位)Short 2个字节Char 2个字节Int ...
- RocketMQ中Broker的消息存储源码分析
Broker和前面分析过的NameServer类似,需要在Pipeline责任链上通过NettyServerHandler来处理消息 [RocketMQ中NameServer的启动源码分析] 实际上就 ...
- 最基础的 ant build 脚本
最基础的 ant build 脚本,根据项目,自行进行修改 <?xml version="1.0" encoding="UTF-8" ?> < ...
- JAVA MQ API方式通信采用Binding MQ Server方式
package com.mqapi; /** * @modified by actorai E-mail:actorai@163.com * @version 创建时间:2010-9-15 * ...
- centos7通过yum安装docker
##yum源安装#1.更新yumyum update #2.删除旧版本yum remove docker \docker-client \docker-client-latest \docker-co ...
- Jedis的配置和优化
参数名:maxTotal 含义:资源池最大连接数 [默认值:8] 使用建议:需要考虑以下几点 1.业务希望的Redis并发量 2.客户端执行命令时间 3.Redis资源:例如应用个数(客户端)* ma ...