題意:有乙個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...