bzoj 2669 局部极小值
来源:互联网 发布:win10如何关闭端口 编辑:程序博客网 时间:2024/06/05 06:26
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 1e9
#define eps 1e-10
#define md 12345678
#define N 1010
using namespace std;
bool mp[6][9],ok[6][9];
int cnt[N];
ll f[1010][100];
int n,m,mxn; ll ans=0;
char st[110];
struct point { int x,y;} q[100];
int lx[8]={1,0,-1,0,1,1,-1,-1},ly[8]={0,1,0,-1,1,-1,1,-1};
ll solve()
{
int tot=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (mp[i][j]) q[tot++]=(point){i,j};
for (int S=0;S<(1<<tot);S++)
{
cnt[S]=0;
memset(ok,0,sizeof(ok));
for (int e=0;e<tot;e++)
{
if (!((S>>e)&1))
{
int i=q[e].x,j=q[e].y;
for (int k=0;k<=7;k++)
{
int x=i+lx[k],y=j+ly[k];
if (x<1||y<1||x>n||y>m) continue;
ok[x][y]=1;
}
} else cnt[S]++;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if ((!ok[i][j]&&(!mp[i][j]))) cnt[S]++;
}
//printf("cnt: "); for (int i=0;i<(1<<tot);i++) printf("%d ",cnt[i]); printf("\n");
memset(f,0,sizeof(f));
f[0][0]=1;
for (int i=0;i<=mxn;i++)
{
for (int S=0;S<(1<<tot);S++)
{
if (i&&(cnt[S]-(i-1))>0) f[S][i]=(f[S][i]+f[S][i-1]*(cnt[S]-(i-1))%md)%md;
if (f[S][i]==0) continue;
for (int j=0;j<tot;j++)
{
if (!((S>>j)&1)) f[S|(1<<j)][i+1]=(f[S|(1<<j)][i+1]+f[S][i])%md;
}
}
}/*
for (int i=0;i<=mxn;i++)
{
for (int S=0;S<(1<<tot);S++) printf("%lld ",f[S][i]);
printf("\n");
}printf("\n");*/
return f[(1<<tot)-1][mxn];
}
void outit()
{
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) printf("%d ",mp[i][j]);
printf("\n");
}
}
void dfs(int dep,int s)
{
//printf("dep: %d %d\n",dep,s); outit();
if (dep>mxn)
{
ll x=solve(); //printf("%lld\n",x);
if (s&1) ans=(ans-x+md)%md; else ans=(ans+x)%md;
return;
}
dfs(mxn+1,s);
for (int now=dep;now<=mxn;now++)
{
int i=(now-1)/m+1,j=(now-1)%m+1;
//printf("%d %d %d\n",now,i,j);
if (!mp[i][j])
{
bool ok=1;
for (int k=0;k<=7;k++)
{
int x=i+lx[k],y=j+ly[k];
if (x<1||y<1||x>n||y>m) continue; //printf("xy: %d %d\n",x,y);
if (mp[x][y]) { ok=0; break;}
}
if (ok)
{
mp[i][j]=1;
dfs(now+1,s+1);
mp[i][j]=0;
}
}
}
}
void check()
{
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
if (mp[i][j])
{
for (int k=0;k<=7;k++)
{
int x=i+lx[k],y=j+ly[k];
if (mp[x][y])
{
printf("0\n");
exit(0);
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
mxn=n*m;
for (int i=1;i<=n;i++)
{
scanf("%s",st+1);
for (int j=1;j<=m;j++) mp[i][j]=st[j]=='X';
}
check();
dfs(1,0);
printf("%d\n",ans);
return 0;
}
- bzoj 2669 局部极小值
- bzoj 2669: [cqoi2012]局部极小值
- BZOJ 2669 局部极小值 CQOI2012
- BZOJ 2669- [cqoi2012]局部极小值
- BZOJ 2669: [cqoi2012]局部极小值
- bzoj 2669: [cqoi2012]局部极小值
- [DP 容斥] BZOJ 2669 [cqoi2012]局部极小值
- HDU 5838 Mountain && BZOJ 2669 局部极小值
- BZOJ 2669([cqoi2012]局部极小值-状态压缩+dp)
- 【CQOI 2012】【JZOJ 4700】【BZOJ 2669】局部极小值
- BZOJ 2669 局部极小值&JZOJ.4700 Garden
- BZOJ 2669 cqoi2012 局部极小值 状压DP+容斥原理
- BZOJ 2669 cqoi2012 局部极小值 状压DP+容斥原理
- bzoj 2669: [cqoi2012]局部极小值(dp+容斥原理)
- 【bzoj 2669】[cqoi2012]局部极小值(状压dp+容斥原理)
- BZOJ 2669: [cqoi2012]局部极小值 状压dp 容斥原理
- 【CQOI2012】局部极小值
- bzoj2669: [cqoi2012]局部极小值
- 练贪心!贪心!贪心!
- bzoj 1060 时态同步 水题?神题?
- dp专题训练
- bzoj 3743 kmap
- web 后端学习记录1_jsp学习记录
- bzoj 2669 局部极小值
- bzoj 1049 数字序列
- bzoj 2121 字符串游戏
- bzoj 2054 疯狂的馒头
- bzoj 2734 集合选数
- bzoj 3594 方伯伯的玉米田
- bzoj 1818/1732 聚会
- heheda的数论专题练习
- bzoj 3997 组合数学