[BZOJ2669][CQOI2012]局部最小值(容斥+状压DP)

发现最多有8个限制位置,可以以此为基础DP和容斥。

$f_{i,j}=f_{i-1,j}\times (cnt_j-i+1)+\sum_{k\subset j} f_{i-1,k}$

$cnt_j$表示当限制状态为j时i有多少个可行位置。

这样DP只能保证所有题设位置全部是局部最小值,但不保证其它位置不会变成局部最小值,容斥解决。

$O(DFS*8nm*2^8)$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 5 using namespace std;
 6 
 7 const int mod=12345678;
 8 int dx[9]={0,1,0,-1,0,1,-1,1,-1},dy[9]={0,0,1,0,-1,1,-1,-1,1};
 9 int n,m,ans,l,f[30][1<<8],cnt[1<<8],vis[8][8],a[10][2];
10 char ch[8][8];
11 
12 int dp(){
13     memset(f,0,sizeof(f));
14     memset(cnt,0,sizeof(cnt));
15     int top=0;
16     rep(i,1,n) rep(j,1,m) if (ch[i][j]=='X')
17         a[++top][0]=i,a[top][1]=j;
18     for (int S=0; S<(1<<top); S++){
19         memset(vis,0,sizeof(vis));
20         rep(i,1,top) if (~S&(1<<(i-1))) vis[a[i][0]][a[i][1]]=1;
21         rep(i,1,n) rep(j,1,m){
22             bool flag=0;
23             rep(l,0,8) if (vis[i+dx[l]][j+dy[l]]) { flag=1; break; }
24             if (!flag) cnt[S]++;
25         }
26     }
27     f[0][0]=1;
28     rep(i,1,n*m) for (int j=0; j<(1<<top); j++){
29         f[i][j]=(f[i][j]+1ll*f[i-1][j]*max(cnt[j]-i+1,0))%mod;
30         rep(k,1,top) if (j&(1<<(k-1)))
31             f[i][j]=(f[i][j]+f[i-1][j^(1<<(k-1))])%mod;
32     }
33     return f[n*m][(1<<top)-1];
34 }
35 
36 void dfs(int x,int y,int t){
37     if (y==m+1){ dfs(x+1,1,t); return; }
38     if (x==n+1){ ans=(ans+dp()*(t&1?-1:1))%mod; return; }
39     dfs(x,y+1,t);
40     bool flag=0;
41     rep(i,0,8) if (ch[x+dx[i]][y+dy[i]]=='X') { flag=1; break; }
42     if (!flag) ch[x][y]='X',dfs(x,y+1,t+1),ch[x][y]='.';
43 }
44 
45 int main(){
46     freopen("bzoj2669.in","r",stdin);
47     freopen("bzoj2669.out","w",stdout);
48     scanf("%d%d",&n,&m);
49     rep(i,1,n) scanf("%s",ch[i]+1);
50     rep(i,1,n) rep(j,1,m) if (ch[i][j]=='X')
51         rep(k,1,8) if (ch[i+dx[k]][j+dy[k]]=='X') { puts("0"); return 0; }
52     dfs(1,1,0); printf("%d\n",(ans+mod)%mod);
53     return 0;
54 }

 

posted @ 2018-09-07 00:31  HocRiser  阅读(250)  评论(0编辑  收藏  举报