P3160 CQOI2012 區域性極小值

2022-05-20 20:25:41 字數 1480 閱讀 3098

p3160 [cqoi2012]區域性極小值

一眼就是狀壓,接下來就不知道了\(qwq\)

我們能手玩出區域性小值最多差不多是\(8,9\)個的樣子,\(dp_\)為填滿\(1~i\)數字,區域性小值的狀態為\(j\)

第\(k\)個區域性極小值填\(i\):\(dp[i][j]=(dp[i][j]+dp[i-1][j^(1<

不填在區域性極小值,顯然有些地方不能填\(i\)的,首先還沒填的區域性極小值不填,其周圍也不能填(填\(i\)後後面再填比不符合區域性極小值)

我們預處理出每種狀態不能填時的位置:\(dp[i][j]=(dp[i][j]+dp[i-1][j]*max(num[j]-i+1,0))%p\)

一頓操作後發現wa了,我們得到的區域性極小值可能不是恰好是給出的\(x\)(更多)

容斥原理:ans=至少多0個極小值-至少多1個極小值+至少多兩個極小值......

理解:至少多0個\((x,x+1,x+2,x+3...)-k(x+1,x+2,x+3...)\)其中\(k\)為某些值的係數

填了至少多0個極小值後,有多填的部分那就得減去至少多1個極小值,至少多1個極小值的位置也有很多,就會有一些位置減掉的係數為(k>1),就要又加上

\(dfs\)時加上能被多餘的極小值填上的地方換成'x',然後多次做\(dp\)

#include#include#include#includeusing namespace std;

typedef long long ll;

const int maxn=31;

const int p=12345678;

const int dx[8]=,dy[8]=;

int n,m,tot;

ll ans;

int x[maxn],y[maxn],num[1<<9],dp[maxn][1<<9];

bool visit[maxn][maxn];

char s[maxn][maxn];

inline int solve()

}for(int j=1;j<=n;++j)

for(int k=1;k<=m;++k)

if(visit[j][k])

++cnt;

num[i]=n*m-cnt;

} memset(dp,0,sizeof(dp));

dp[0][0]=1;

for(int i=1;i<=n*m;++i)

for(int j=0;jreturn dp[n*m][up-1];

}void dfs(int x,int y,int k)

if(x==n+1)

dfs(x,y+1,k);

if(s[x][y]!='x')

if(f) }}

int main()

/*5 5

.....

...x.

.x...

.....

....x

*/

CQOI2012 區域性極小值

很明顯這題是dp,不過比賽的時候沒有考慮狀壓。因為有x的點最多只有8個,那麼可以考慮狀壓。因為要求有x的點比周圍的點小,那麼可以把數從小到大填。設f i j 表示數值已經填到了第i個數,x點填的狀態為j。轉移方程 f i j k jf i 1 j k ma x 0,rest j i 1 f i 1 ...

bzoj2669 CQOI2012 區域性極小值

洛谷bzoj 這道題的方法是用dfs進行搜尋容斥時,dp統計答案 感覺痛苦的同學建議做做 乙個區域性最小值就可以覆蓋最少四個點 放在四個角上 最多九個 放在中間 所以最多隻會有8個區域性最小值,可以考慮一下狀壓 我們可以考慮從小到大地放入每個元素 dp i j 表示在選擇的區域性最小值狀態為j時,已...

CQOI2012 區域性極小值

將1,2,3 m n填入乙個m n m nm n的矩陣,要求一些位置滿足比周圍八個數都小,且其他位置不滿足,則一共有幾種方案.首先不考慮 其他位置不滿足 這個要求,因為資料範圍很小,因此最多有8個位置符合條件,可以狀壓dp.考慮將m n m nm n個數從小到大依次填入矩陣,用dp i j dp i...