AHOI2009 中國象棋 巧妙DP

2021-08-15 14:13:26 字數 1233 閱讀 8025

* [ahoi2009]中國象棋*

題目描述

這次小可可想解決的難題和中國象棋有關,在乙個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

emm……此題做法我們簡稱為「猥瑣使用乘法原理和加法原理」,嘿嘿嘿。

神奇。ps.自定義函式c(x)的部分,用define寫會迷之wa掉……

#include

#include

#include

using

namespace

std;

#define ll long long

const

int n=101;const

int mo=9999973;

ll dp[n][n][n];int n,m;

int c(int x)

/*巧妙dp:

dp[i][j][k]表示:

放了前i行,有j列有1個棋子,有k列有兩個棋子

轉移方程見**

此方法易懂卻不好想到

*/#if 0

writers: goes && g.s.m.

銳意進取;

#endif

int main()

ll ans=0;

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

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

ans=(ans+dp[n][i][j])%mo;

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

0;}

AHOI2009中國象棋 巧妙dp

題目意思是在乙個n m n,m 100 的矩形裡放任意多個棋子,滿足任一行任一列都最多只有2個棋子,求方案數。考慮用dp,設三維dp i j k 代表列舉到i行,有j列只有1個棋子,k列有2個棋子的方案數,那麼放0個棋子的列數就是m j k了。在第i行只能放0,1,2個棋子,那麼我們模擬一下,就可以...

AHOI2009中國象棋

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

AHOI2009 中國象棋

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