這道題主要是狀態很難想到
首先可以看出每行每列不能超過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個 使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是 乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起鍛鍊一下思...