[DP 容斥] BZOJ 2669 [cqoi2012]局部极小值

来源:互联网 发布:正版bim软件多少钱 编辑:程序博客网 时间:2024/05/15 23:31

从小到大放 如果一个格子是极小值 一定比周围先放 根据这个dp

但是这样不保证其他地方也成为极小值 那么容斥一下 最多8个是极小值


#include<cstdio>#include<cstdlib>#include<vector>#include<algorithm>#include<cstring>#define cl(x) memset(x,0,sizeof(x))using namespace std;typedef pair<int,int> abcd;typedef long long ll;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(int &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}inline void read(char &x){for (x=nc();x!='.' && x!='X';x=nc());}#define P(x,y) (((x)-1)*m+(y))const int MOD=12345678;const int dx[]={0,0,1,-1,1,1,-1,-1};const int dy[]={1,-1,0,0,-1,1,-1,1};int n,m;int vst[10][10],flag[10][10];vector<abcd> tmp;abcd Pos[20];int cnt,tot;int sum[1<<10],cot[1<<10];ll f[30][1<<10];ll ans;inline void DP(){cl(f); cl(sum); cl(cot);for (int s=0;s<(1<<cnt);s++){cl(flag);for (int i=1;i<=cnt;i++){flag[Pos[i].first][Pos[i].second]=1;if (~s>>(i-1)&1){for (int k=0;k<8;k++){int sx=Pos[i].first+dx[k],sy=Pos[i].second+dy[k];if (sx<=0 || sy<=0 || sx>n || sy>m) continue;flag[sx][sy]=1;}}elsecot[s]++;}for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)sum[s]+=flag[i][j]^1;}f[0][0]=1; cl(flag); for (int i=1;i<=cnt;i++)flag[Pos[i].first][Pos[i].second]=i;for (int t=1;t<=n*m;t++){for (int k=1;k<=cnt;k++){int ss=1<<(k-1);for (int s=0;s<(1<<cnt);s++)if (!(s&ss))(f[t][s|ss]+=f[t-1][s])%=MOD;}for (int s=0;s<(1<<cnt);s++)(f[t][s]+=(ll)(sum[s]-((t-1)-cot[s]))*f[t-1][s]%MOD)%=MOD;}if ((cnt-tot)&1)ans+=MOD-f[n*m][(1<<cnt)-1];elseans+=f[n*m][(1<<cnt)-1];ans%=MOD;}inline void dfs(){cnt=0;for (int j=0;j<(signed)tmp.size();j++)Pos[++cnt]=tmp[j];DP();for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)if (!vst[i][j]){vst[i][j]++;for (int k=0;k<8;k++){int sx=i+dx[k],sy=j+dy[k];if (sx<=0 || sy<=0 || sx>n || sy>m) continue;vst[sx][sy]++;}tmp.push_back(abcd(i,j));dfs();tmp.pop_back();vst[i][j]--;for (int k=0;k<8;k++){int sx=i+dx[k],sy=j+dy[k];if (sx<=0 || sy<=0 || sx>n || sy>m) continue;vst[sx][sy]--;}}}int main(){char ch; int sta=0;read(n); read(m);for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){read(ch); if (ch=='X') {tot++; tmp.push_back(abcd(i,j)); vst[i][j]++;for (int k=0;k<8;k++){int sx=i+dx[k],sy=j+dy[k];if (sx<=0 || sy<=0 || sx>n || sy>m) continue;vst[sx][sy]++;}}}dfs();printf("%lld\n",ans);return 0;}


0 0