[luoguP2051] [AHOI2009]中国象棋(DP)】的更多相关文章

P2051 [AHOI2009]中国象棋 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个 \(N\) 行 \(M\) 列的棋盘上,让你放若干个炮(可以是 \(0\) 个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子.你也来和小可可一起锻炼一下思维吧! 输入输出格式 输入格式: 一行包含两个整数 \(N\) , \(M\) ,之间由一个空格隔开.…
https://www.luogu.org/problemnew/show/P2051 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子.你也来和小可可一起锻炼一下思维吧! 输入输出格式 输入格式: 一行包含两个整数N,M,之间由一个空格隔开. 输出格式: 总共的方…
传送门 注释写明了一切 #include <cstdio> #define N 111 #define p 9999973 #define LL long long int n, m; LL ans, f[N][N][N]; //每一行和每一列可以放0/1/2个炮 //f[i][j][k]表示前i行放了1个炮的列有j个,放了2个炮的列有k个的方案数 //那么可以推出,放了0个炮的列有m-j-k个 inline int C(int x) { return x * (x - 1) / 2; } i…
象棋,给你棋盘大小,然后放炮(炮的数量不限),不能让炮打到其他的炮,问方案数: 数据n,m<=200; 状态压缩似乎能做,但是我不会: 因为只要状态数,所以不必纠结每种状态的具体情况: 可以想出每行每列最多放两个棋子(我想到了吗?): 所以(为什么啊) 设计f[i][j][k] 表示DP到第i行,一列只有一个棋子的有j个,一列只有两个棋子的有k个: 清晰(模糊)转移方法 好,我们终于来到了第i行,加油: 这位OIer并不打算把棋子放在这一行,用f[i][j][k]直接继承f[i-1][j][k]…
Description 在 $n * m$ 的格子上放若干个炮, 使得每个炮都不能攻击到其他炮 Solution 定义数组f[ i ][ j ][ k ] 表示到了第 i 行, 已经有2个炮的列数为 j, 有1个炮的列数 为k, 的方案数有多少. 然后就能非常简单的写个dp了 Code #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define rep(i,a,b…
题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\(k\)列放了两个的方案数 转移很显然 Code #include<bits/stdc++.h> #define LL long long #define RG register using namespace std; template<class T> inline void rea…
DP,递推,组合数 其实相当于就是一个递推推式子,然后要用到一点组合数的知识 一道很妙的题,因为不能互相攻击,所以任意行列不能有超过两个炮 首先令f[i][j][k]代表前i行,有j列为一个炮,有k列为两个炮的方案 那么有如下转移: 1,这行不放炮,add+=f[i-1][j][k]; 2,放一个炮,并且放在没有炮的那列 add+=f[i-1][j-1][k] * (m - j - k + 1);,因为放了这个炮后, 一个炮的变多了,也就是上一行的j+1得到这一行的j,所以上一行的j就是j-1,…
题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子的有k列,则放了2个棋子的为(m-j-k)列 则放棋子一共可分为6种情况 不放棋子:1.f[i+1][j+2][k] += f[i][j][k] 放一个棋子:2.放在没有棋子的那一列 f[i+1][j-1][k+1] += f[i][j][k]*j 3.放在有棋子的那一列 f[i+1][j][k-1…
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去,所以每一行每一列最多放置两个炮. 这样子我们就可以试着压缩状态,记录前i行有几列是放一个棋子的,有几列是放两个棋子的,有几列是不放棋子的. 即设dp[ i ][ j ] [ k ] 表示前 i 行,有 j 列是放一个棋子的,有k列是放两个棋子的,有 m - j - k列是不放棋子的. 又由于每行最…
题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接爆搜水过 复杂度O(n^m(吧)) 50pt: n<=100,m<=8 是状压/网络流的复杂度 当然,这题显然是状压 由题可以得出一个很显然但很重要的废话:每行每列只能放0~2个棋子 因此,我们可以考虑写一个3进制的状压DP 设f[i][j]表示第 i 行,每一列的具体情况以三进制的表达形式存在j…