这道题的难点在于思考dp表示什么

首先可以令ans[len]表示白色子矩阵边长最大值大于等于len的方案数则ans[len]-ans[len+1]就是beautifulness为len的方案数

白色子矩阵边长最大值大于等于len的方案数=总方案-白色子矩阵边长最大值小于len的方案数

经过这样的转化,我们就好dp了,我们先穷举len

令f[i][st]表示到第i行,状态为st的白色子矩阵边长最大值小于len的方案数

怎么设计状态呢,由于要保证白色子矩阵边长最大值小于len

我们维护一个n-len+1的len进制数,第j位表示(i,j)~(i,j+len-1)中向上延伸的白色格子数的最小值

这样我们二进制穷举每行的涂色方法就可以转移状态了

 #include<bits/stdc++.h>

 using namespace std;
typedef long long ll;
const int mo=1e9+;
int d[],a[],ans[],v[],n;
char s[];
void inc(int &a,int b)
{
a+=b;
if (a>mo) a-=mo;
} struct node
{
int st[],c[],len;
void clr()
{
for (int i=; i<=len; i++) c[st[i]]=;
len=;
}
void push(int nw,int w)
{
if (!c[nw]) st[++len]=nw;
inc(c[nw],w);
}
} f[];
int main()
{
int cas;
scanf("%d",&cas);
f[].len=f[].len=;
while (cas--)
{
int m=;
scanf("%d",&n);
for (int i=; i<=n; i++)
{
scanf("%s",s);
a[i]=;
for (int j=; j<n; j++)
if (s[j]=='o') m=m*%mo;
else a[i]|=(<<j);
}
ans[]=;
ans[]=(m-+mo)%mo;
for (int l=; l<=n; l++)
{
int p=,k=n+-l;
d[]=;
for (int i=; i<=n; i++) d[i]=d[i-]*l;
f[].clr();
f[].push(,);
for (int i=; i<=n; i++)
{
p^=;
f[p].clr();
for (int cur=; cur<(<<n); cur++)
{
if (cur&a[i]) continue;
for (int r=; r<k; r++) v[r]=;
for (int r=; r<n; r++)
{
if ((cur>>r)&) continue;
for (int j=; j<k; j++)
if (r>=j&&r<j+l) v[j]=;
}
for (int j=; j<=f[p^].len; j++)
{
int pre=f[p^].st[j],nw=;
int w=f[p^].c[pre];
for (int r=; r<k; r++)
{
int x=pre%l; pre/=l;
if (v[r]) continue;
if (x==l-) {nw=-; break;}
nw+=(x+)*d[r];
}
if (nw>-) f[p].push(nw,w);
}
}
}
ans[l]=;
for (int i=; i<=f[p].len; i++)
{
int x=f[p].st[i];
inc(ans[l],f[p].c[x]);
}
ans[l]=(m-ans[l]+mo)%mo;
ans[l-]=(ans[l-]-ans[l]+mo)%mo;
}
for (int i=; i<=n; i++)
printf("%d\n",ans[i]);
}
}

hdu5079的更多相关文章

随机推荐

  1. PokeCats开发者日志(三)

      现在是PokeCats游戏开发的第四天的晚上,明天要过周末了,所以提前写一下开发者日志吧! day4   day4主要是优化界面和增加游戏可玩性.   (1)感觉只有三只喵喵的话,玩家只需要无脑点 ...

  2. maven中如何得到父工程的位置

    目前的项目是一个父子工程项目,想要在子工程的pom文件中操作父工程目录下的资源. maven官方提供了标准的写法,比如parent.basedir之类的,网上可以找到很多,但尝试了之后就是不识别. 搞 ...

  3. [剑指Offer] 30.连续子数组的最大和

    题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...

  4. 对Web作用域变量进行迭代

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ pa ...

  5. poj 1034 The dog task (二分匹配)

    The dog task Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2559   Accepted: 1038   Sp ...

  6. [LINUX]警告:检测到时钟错误。您的创建可能是不完整的。

    [LINUX]警告:检测到时钟错误.您的创建可能是不完整的.   原因:     如果上一次编译时为20071001,你把系统时间改成20070901后再编译就会报这样的错误. 解决:     把时间 ...

  7. 深入理解Netscaler INat

    深入理解Netscaler INat http://blog.51cto.com/caojin/1898173 Netscaler的INat主要是用作基于目的地址的转换,将client访问的公网IP通 ...

  8. [洛谷P1337][JSOI2004]平衡点 / 吊打XXX

    题目大意:有$n$个重物,每个重物系在一条绳子上.所有绳子系在一起,问绳结最终平衡于何处. 题解:$NOIP$前学学模拟退火,但发现我脸好黑啊... 卡点:脸黑 C++ Code: #include ...

  9. ZOJ 3229 Shoot the Bullet | 有源汇可行流

    题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...

  10. ZOJ 2314 Reactor Cooling | 无源汇可行流

    题目: 无源汇可行流例题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题解: 证明什么的就算了,下面给出一种建图方式 ...