棋盤遊戲 51Nod 1327

2021-10-23 09:08:13 字數 1596 閱讀 1945

題解:在放置棋子時僅僅要求左右滿足條件與n的順序無關,考慮乙個二維dp陣列,dp[i][j]代表放到了第i列還有j列沒有放棋子,但是這個二維dp沒有維護右限的資訊,所以考慮增加一維代表有多少行到達了右限但沒有棋子,將l和r區間的限制統計,可以得到dp轉移方程:

dp[a+1][b+1-l[a+1]][c+r[a+1]]+=dp[a][b][c]*sum[b+1][l[a+1]]%mod;

列舉到當第i列,有l[i]行必須要放左區間了,從空的列中選擇放入當前列不放入,同時加上到達右限的區間

dp[a+1][b-l[a+1]][c+r[a+1]]+=dp[a][b][c]*sum[b][l[a+1]]%mod*num[a+1]%mod; 

列舉到當第i列,有l[i]行必須要放左區間了,從空的列中選擇放入當前列放作用於不在左右限制的行,同時加上到達右限的區間

dp[a+1][b-l[a+1]][c+r[a+1]-1]+=dp[a][b][c]*sum[b][l[a+1]]%mod*(c+r[a+1])%mod;

列舉到當第i列,有l[i]行必須要放左區間了,從空的列中選擇放入但是當前列放入右限區間,同時加上到達右限的區間

比較難!!!!!

ac**:

#include#include#include#include#include#include#include#include#include#include#define ll long long

using namespace std;

int read()

const int maxn=2e2+10;

const ll mod=1e9+7;

ll dp[maxn][maxn][55];

ll sum[maxn][maxn];

int l[maxn],r[maxn],num[maxn];

int main( )

for(int a=1;a<=n;a++)

for(int a=2;a<=m;a++) num[a]+=num[a-1];

dp[0][0][0]=1;

for(int a=0;a=l[a+1])

dp[a+1][b+1-l[a+1]][c+r[a+1]]+=dp[a][b][c]*sum[b+1][l[a+1]]%mod,dp[a+1][b+1-l[a+1]][c+r[a+1]]%=mod;

if(b>=l[a+1])

dp[a+1][b-l[a+1]][c+r[a+1]]+=dp[a][b][c]*sum[b][l[a+1]]%mod*num[a+1]%mod,dp[a+1][b-l[a+1]][c+r[a+1]]%=mod;

if(b>=l[a+1]&&c+r[a+1]>=1)

dp[a+1][b-l[a+1]][c+r[a+1]-1]+=dp[a][b][c]*sum[b][l[a+1]]%mod*(c+r[a+1])%mod,dp[a+1][b-l[a+1]][c+r[a+1]-1]%=mod;}}

}ll ans=0;

for(int a=0;a<=m;a++) ans=(ans+dp[m][a][0])%mod;

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

}

51nod 1327 棋盤遊戲

有乙個n行m列的棋盤,即該棋盤被分為n m格。現在向棋盤中放棋子,每個格仔中最多放乙個棋子,也可以乙個不放。放完棋子後需要滿足如下要求 1 對於第i行來說,其從左往右的前left i 個格仔 即最左側的left i 個連續的格仔 中恰好一共有1個棋子 2 對於第i行來說,其從右往左的前right i...

51nod1327 棋盤遊戲 dp

description 有乙個n n 行m role presentation style position relative m m列的棋盤,即該棋盤被分為n m n m 格。現在向棋盤中放棋子,每個格仔中最多放乙個棋子,也可以乙個不放。放完棋子後需要滿足如下要求 1 1 對於第i行來說,其從左往...

題解 51nod 1327 棋盤遊戲

51nod 1327 棋盤遊戲 求合法方案數 這題挺妙的,雖然可能妙得不是非常直觀 首先,因為考慮每一列只能填乙個,考慮怎麼填 宣告 l i 為以 i 為左區間右端點的行數,r i 為以 i 為右區間左端點的行數,mid i 為第 i 列上有多少沒有被左右區間覆蓋的行數 於是可以設計乙個狀態 f i...