hdu5079
这道题的难点在于思考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的更多相关文章
随机推荐
- 在C的头文件中定义的结构体,如何在cpp文件中引用
解决方案1:在cpp文件中放置.c,且在该文件中引用变量 解决方案2:在一个cpp文件中包含.c,但在另一个cpp文件中使用结构体变量 cpp文件1 cpp文件2 #include "dia ...
- 算法(5)Jump Game
题目:非负数的数组,每个数组元素代表这你能最大跨越多少步,初始在0的位置,问,能不能正好调到数组的最后一位! https://leetcode.com/problems/jump-game/#/des ...
- Beats数据采集
Beats数据采集 Beats是elastic公司的一款轻量级数据采集产品,它包含了几个子产品: packetbeat(用于监控网络流量). filebeat(用于监听日志数据,可以替代logstas ...
- 习题:就是干(DP)
洛谷2301 题目描述 眼看着老师大军浩浩荡荡的向机房前进.LOI 的同学们决定动用自己的力量来保卫他们的好朋友loidc.现在每个人都要挑选自己的武器——两根木棍.一根用做远距离投掷,另一根用做近距 ...
- 纯Div+Css制作的漂亮点击按钮和关闭按钮
纯Div+Css制作的漂亮点击按钮和关闭按钮,单击点击按钮也有效果.这些都不是图片.
- P2563 [AHOI2001]质数和分解
题目描述 任何大于 1 的自然数 n 都可以写成若干个大于等于 2 且小于等于 n 的质数之和表达式(包括只有一个数构成的和表达式的情况),并且可能有不止一种质数和的形式.例如,9 的质数和表达式就有 ...
- hdu6103 Kirinriki(trick+字符串)
题解: 考虑一开始时,左边从1开始枚举,右边从n开始枚举 我们可以得到一个最大的值k. 但是如果这样依次枚举,复杂度肯定是n^3,是不行的 考虑如何利用上一次的结果,如果我们把1和n同时去掉 就可以利 ...
- How to Create a Perl Based Custom Monitor on NetScaler
How to Create a Perl Based Custom Monitor on NetScaler https://support.citrix.com/article/CTX227727 ...
- 【BZOJ 2434】 [Noi2011]阿狸的打字机 fail树+树状数组
就是考了一个fail树的神奇应用我们建出fail树之后,发现我们就是在求y到根的路径上所有的点在以x为根的子树里的个数,这个我们离线后用树状数组+dfs序即可解决 #include <cstdi ...
- 用boost::lexical_cast进行数值转换
在STL库中,我们可以通过stringstream来实现字符串和数字间的转换: int i = 0; stringstream ss; ss << "123"; ...