題目
有乙個n行m列的整數矩陣,其中1到nm之間的每個整數恰好出現一次。如果乙個格仔比所有相鄰格仔(相鄰是指有公共邊或公共頂點)都小,我們說這個格仔是區域性極小值。
給出所有區域性極小值的位置,你的任務是判斷有多少個可能的矩陣。
思路看到資料範圍馬上想到狀壓dp。
先分析狀態數,會發現區域性極小值在一張圖中最多只有8個,所以狀態為已經實現了哪些區域性極小值。\(dp[i][s]\)為已經填完數\([1,i]\),滿足區域性極小值為\(s\)的方案數。
則考慮從已知的位置向後轉移,下乙個填數的位置可以是某個未填的區域性極小值,也可以是除了未填過的區域性最小值旁邊的點之外的其它點,我們可以預處理這些點的數目\(num[i]\)。
兩個轉移方程如下:
\[dp[i+1][s+(1<
然後要注意的是狀態的定義:我們當前的\(dp\)值僅僅滿足了需要成為區域性極小值的點成為了區域性極小值,而不能保證是否除了這些點之外還有其它的區域性極小值,所以這裡做乙個容斥就好了。
**
#include#define ll long long
using namespace std;
const int mod=12345678;
void add(int &x,int y)
int n,m;
char s[15][15];
struct nodep[10];
bool check(int x,int y)
int dp[30][1<<8|5],tt,cnt[1<<8|5];
bool vis[15][15],mark[5][8];
int calc();
add(res,dfs(x,y+1,f));tt--;
return res;
} bool flag=1;
for(int i=x-1;i<=x+1;i++)
for(int j=y-1;j<=y+1;j++)
if(s[i][j]=='x'||vis[i][j])flag=0;
if(flag);vis[x][y]=1;
add(res,dfs(x,y+1,-f));tt--;vis[x][y]=0;
} add(res,dfs(x,y+1,f));
return res;
}int main()
bzoj 2669 區域性極小值
bzoj 2669 區域性極小值 有乙個n行m列的整數矩陣,其中1到nm之間的每個整數恰好出現一次。如果乙個格仔比所有相鄰格仔 相鄰是指有公共邊或公共頂點 都小,我們說這個格仔是區域性極小值。給出所有區域性極小值的位置,你的任務是判斷有多少個可能的矩陣。有乙個和dp求n的排列中有k個逆序對的方案數一...
bzoj2669 CQOI2012 區域性極小值
洛谷bzoj 這道題的方法是用dfs進行搜尋容斥時,dp統計答案 感覺痛苦的同學建議做做 乙個區域性最小值就可以覆蓋最少四個點 放在四個角上 最多九個 放在中間 所以最多隻會有8個區域性最小值,可以考慮一下狀壓 我們可以考慮從小到大地放入每個元素 dp i j 表示在選擇的區域性最小值狀態為j時,已...
bzoj2669 cqoi2012 區域性極小值
題目鏈結 給出乙個 n m 的整數矩陣,其中 1,nm 中的整數每個出現一次,有一些位置為區域性最小值。問方案數。好神的dp啊。cnt j 表示的是,在區域性最小值被填充的狀態為 j 的情況下,目前有多少個位置可以填,這些位置中包括已經被填了數的位置。最後加模再取模 bzoj2669 include...