这道题的难点在于思考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. hdu 1787 GCD Again (欧拉函数)

    GCD Again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  2. P1419 寻找段落

    题目描述 给定一个长度为n的序列a_i,定义a[i]为第i个元素的价值.现在需要找出序列中最有价值的“段落”.段落的定义是长度在[S,T]之间的连续序列.最有价值段落是指平均值最大的段落, 段落的平均 ...

  3. CF#366 704D Captain America 上下界网络流

    CF上的题,就不放链接了,打开太慢,直接上题面吧: 平面上有n个点, 第 i 个点的坐标为 ($X_i ,Y_i$), 你需要把每个点染成红色或者蓝色, 染成红色的花费为 r , 染成蓝色的花费为 b ...

  4. [Leetcode] merge sorted array 合并数组

    Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assume th ...

  5. [模拟赛] StopAllSounds

    Description 小松鼠开心地在树之间跳跃着,突然她停了下来.因为眼前出现了一个 拿着专克超萌小松鼠的法宝----超萌游戏机的游客! 超萌游戏机之所以拥有这个名字,是因为它的屏幕是一个n × 2 ...

  6. POJ3189:Steady Cow Assignment(二分+二分图多重匹配)

    Steady Cow Assignment Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7482   Accepted: ...

  7. 用Hibernate实现分页查询

    分页查询就是把数据库中某张表的记录数进行分页查询,在做分页查询时会有一个Page类,下面是一个Page类,我对其做了详细的注解: package com.entity; /** * @author:秦 ...

  8. remove computer from join with powershell

    Removes the local computer from its domain. Remove-Computer [-UnjoinDomainCredential] <PSCredenti ...

  9. Android百度地图的使用

    做关于位置或者定位的app的时候免不了使用地图功能,本人最近由于项目的需求需要使用百度地图的一些功能,所以这几天研究了一下,现写一下blog记录一下,欢迎大家评论指正! 一.申请AK(API Key) ...

  10. 【BZOJ2820】YY的GCD [莫比乌斯反演]

    YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 求1<=x<=N, ...