洛谷 P2051 AHOI2009 中國象棋

2021-08-28 03:34:09 字數 1185 閱讀 2620

這道題主要是狀態很難想到

首先可以看出每行每列不能超過2個棋子

也就是說有0, 1, 2三種狀態

所以可以一行一行來處理

那就用放了0個棋子的列數是

那麼這個時候狀態轉移方程就非常好寫了。

對於當前這一行可以不放,放乙個,放兩個棋子

0表示沒有棋子的列,1表示有1個棋子的列。

那麼有幾種情況

不放放乙個在0

放乙個在1

放兩個都在0

放兩個乙個0乙個1

放兩個在1

放兩個乙個0乙個1為例

方程為這裡用刷表法,比填表法方便非常多,但是要注意有些狀態是不存在的(比如

所以一開始要判斷之前有沒有刷到過這個狀態

現在解釋乙個這個方程

現在是第i行,要填i+1行

放乙個在0的話,就有乙個0變成1

所以j要加1

放乙個在1的話,就有乙個1變成2

所以j要減1,k要加1

這裡0的列數不用管,因為推出j和k就可以知道0的列數了(m-j-k)

所以j加1又減1,所以不變,而k+1

所以是那麼放乙個在0乙個在1的方法顯然是0的列數乘上1的列數

所以就是

最後就是把最後一行的所有情況加起來就是答案

注意可以用define來簡化**

#include#include#define rep(i, a, b) for(int i = (a); i < (b); i++)

#define _for(i, a, b) for(int i = (a); i <= (b); i++)

#define cal(a, b) a = (a + b) % mod

using namespace std;

const int mod = 9999973;

const int maxn = 112;

long long f[maxn][maxn][maxn], n, m, ans;

int main()

_for(j, 0, m)

for(int k = 0; k + j <= m; k++)

cal(ans, f[n][j][k]);

printf("%lld\n", ans);

return 0;

}

洛谷 P2051 AHOI2009 中國象棋

題目描述 這次小可可想解決的難題和中國象棋有關,在乙個n行m列的棋盤上,讓你放若干個炮 可以是0個 使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是 乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起...

洛谷 P2051 AHOI2009 中國象棋

題目 中國象棋 思路 首先是30分暴力 直接dfs就好。用row和col儲存狀態。include using namespace std define maxn 100 define read x scanf d x define md 9999973 int n,m int rw maxn 5 c...

洛谷 P2051 AHOI2009 中國象棋

這次小可可想解決的難題和中國象棋有關,在乙個n行m列的棋盤上,讓你放若干個炮 可以是0個 使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是 乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起鍛鍊一下思...