ACdream1132 chess 狀態壓縮DP

2021-06-22 20:08:03 字數 1131 閱讀 7939

題意:有乙個n*n的棋盤,要在上面放將,乙個將可以控制本身的位置和上下左右四格,棋盤上有一些地方不能放將,但是這些點也要被控制,問最少要放幾個將。

思路:狀態壓縮dp,我們反過來想,最多空多少格不放,能控制所有的格仔。

對於資料,我們先做乙個預處理,求出每行可以的狀態和這個狀態對應空的格數,這裡我用f[i][j]表示第i行在j狀態下空的格數,如果j狀態不可以則賦值-1。之後我也求出乙個每種狀態的控制範圍,用ff[j]表示j狀態下這一行控制的情況。

這些做完後就是乙個dp的過程,對於第i行的控制情況,和第i-1行的放置情況有關係,當然,這裡第一行除外,同時第i行一定要確保第i-1行未被控制的格仔能控制到,第i行和i-1行在同一列不可能都有放置,等等一系列情況考慮之後,可以用下面的狀態轉移方程:

dp[i][j][ff[j]|k]=max(dp[i][j][ff[j]|k],dp[i-1][k][l]+f[i][j]);

這裡i代表第i行,j代表第i行的放置狀態,k代表第i-1行的放置狀態,ff[j]|k 即為第i行的控制狀態,l為第i-1行控制狀態。

處理完所有行後,看最後一行全被控制的狀態,取最大值。然後將格仔數減它就能得到答案了,不可能的情況酌情判斷。

#include#include#include#include#include#include#include#include#includeusing namespace std;

int m,n;

bool h[11][11];

int f[11][555];

int ff[555];

int dp[11][555][555];

void pre()

if(cnt)

cnt=1;

}else

r/=2;

}if(ok)f[i][j]=-1;

else}}

for(int i=0;i0;k--)

if(r%2)t=(t|(1<<(n-2)));

t=(t|i);

ff[i]=t;

}}int main()

{ int x,y;

while(scanf("%d%d",&n,&m)!=eof)

{memset(h,0,sizeof(h));

for(int i=0;i

SSL1132 編碼問題

description 設有乙個陣列a array 0.n 1 of integer 存放的元素為0 n 1 1a j i j 例如當n 6時,有 a 4,3,0,5,1,2 此時,陣列a的編碼定義如下 a 0 編碼為0,a i 編碼為 在a 0 a 1 a i 1 中比a i 的值小的個數i 1,...

1132 數字字元統計

time limit 1 sec memory limit 128 mb submit 3906 solved 2078 submit status web board 對於給定的乙個字串,統計其中數字字元出現的次數。字串長度不超過1000.輸入資料有多行,第一行是乙個整數n,表示測試例項的個數,後...

acdream 1056 (黑白染色)

題意 給你一些關係,每個關係是兩隻馬的名字,表示這兩個馬不能在乙個分組裡,問你能否將這些馬分成兩組。黑白染色,相鄰的點染不同顏色。bfs搞即可,水題。this code is made by wangzhili problem 1056 verdict accepted submission dat...