中國象棋 AHOI2009

2022-05-01 03:54:06 字數 1564 閱讀 6209

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

一行包含兩個整數n,m,之間由乙個空格隔開。

總共的方案數,由於該值可能很大,只需給出方案數模9999973的結果。

輸入樣例#1: 

1 3

輸出樣例#1: 

7

樣例說明

除了3個格仔裡都塞滿了炮以外,其它方案都是可行的,所以一共有2*2*2-1=7種方案。

資料範圍

100%的資料中n和m均不超過100

50%的資料中n和m至少有乙個數不超過8

30%的資料中n和m均不超過6

前30%明顯是暴力

50%是狀壓,不過是3進製下的,不太好寫...

乙個明顯的結論是不同的列(行)之間任意交換對答案是沒有影響的。所以我們可以不用記錄棋子防止的具體資訊。我們設f[i][j][k]表示前i列有j列放了乙個棋子、k列放了兩個棋子的方案數。

那麼再考慮這個狀態能由哪些狀態轉移過來。

首先是第i列乙個棋子也不放,那麼f[i][j][k] = f[i-1][j][k]

其次是放乙個,這時有兩種情況;最後是放兩個,有三種情況。請讀者自己思考=-=

1

//f[i][j][k]表示前i行中有j列放了1個炮,k列放了兩個炮的種類數 2//

f[i][j][k] = f[i-1][j][k] (乙個都不放 3//

+ f[i-1][j-1][k]*(m-j-k+1) + f[i-1][j+1][k-1]*(j+1) (放1個 4//

+ f[i-1][j-2][k]*c(m-j-k+2,2) + f[i-1][j][k-1]*j*(m-j-k+1) + f[i-1][j+2][k-2]*c(j+2,2) (放2個

5 #include6 #include7 #include8

#define ll long long

9#define ri register int

10#define ki 9999973

11using

namespace

std;

12const

int inf = 0x7ffffff;13

const

int n = 100 + 10;14

15 inline int

read()

23int

n, m ; ll f[n][n][n] ;

2425 inline ll c(int x,int y) //

y都是2

26int

main() 39}

40}41int ans = 0;42

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

45 printf("%d"

,ans) ;

46return0;

47 }

中國象棋(AHOI2009)

傳送門 簡單思路 dp 用f i j k 表示前i行有j列放了乙個子,有k列放了兩個子 轉移,只要列舉每一行的放置情況即可,有 不放 在空列放乙個,在有乙個子的列放乙個,在兩個空列各放乙個,在兩個一子列各放乙個,在空列和一子列各放乙個。列舉ijk即可,最後求和 注意 逆元只有在進行除法前需要取模時才...

AHOI2009中國象棋

狀態很難想。本題難就難在如何定狀態。再看題解之前,我一點思路也沒有。看到題解的狀態表示後,我立刻知道怎麼做了。f i j k 表示至第i行,有j列放1個,有k列放2個。這樣f i j k 即為第i行不放 放1個 放2個的數量總和。狀態轉移方程很長,用到組合的相關知識。i 1時需特殊處理。詳見 inc...

AHOI2009 中國象棋

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