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...