这道题的难点在于思考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)中向上延伸的白色格子数的最小值

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

  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef long long ll;
  5. const int mo=1e9+;
  6. int d[],a[],ans[],v[],n;
  7. char s[];
  8. void inc(int &a,int b)
  9. {
  10. a+=b;
  11. if (a>mo) a-=mo;
  12. }
  13.  
  14. struct node
  15. {
  16. int st[],c[],len;
  17. void clr()
  18. {
  19. for (int i=; i<=len; i++) c[st[i]]=;
  20. len=;
  21. }
  22. void push(int nw,int w)
  23. {
  24. if (!c[nw]) st[++len]=nw;
  25. inc(c[nw],w);
  26. }
  27. } f[];
  28. int main()
  29. {
  30. int cas;
  31. scanf("%d",&cas);
  32. f[].len=f[].len=;
  33. while (cas--)
  34. {
  35. int m=;
  36. scanf("%d",&n);
  37. for (int i=; i<=n; i++)
  38. {
  39. scanf("%s",s);
  40. a[i]=;
  41. for (int j=; j<n; j++)
  42. if (s[j]=='o') m=m*%mo;
  43. else a[i]|=(<<j);
  44. }
  45. ans[]=;
  46. ans[]=(m-+mo)%mo;
  47. for (int l=; l<=n; l++)
  48. {
  49. int p=,k=n+-l;
  50. d[]=;
  51. for (int i=; i<=n; i++) d[i]=d[i-]*l;
  52. f[].clr();
  53. f[].push(,);
  54. for (int i=; i<=n; i++)
  55. {
  56. p^=;
  57. f[p].clr();
  58. for (int cur=; cur<(<<n); cur++)
  59. {
  60. if (cur&a[i]) continue;
  61. for (int r=; r<k; r++) v[r]=;
  62. for (int r=; r<n; r++)
  63. {
  64. if ((cur>>r)&) continue;
  65. for (int j=; j<k; j++)
  66. if (r>=j&&r<j+l) v[j]=;
  67. }
  68. for (int j=; j<=f[p^].len; j++)
  69. {
  70. int pre=f[p^].st[j],nw=;
  71. int w=f[p^].c[pre];
  72. for (int r=; r<k; r++)
  73. {
  74. int x=pre%l; pre/=l;
  75. if (v[r]) continue;
  76. if (x==l-) {nw=-; break;}
  77. nw+=(x+)*d[r];
  78. }
  79. if (nw>-) f[p].push(nw,w);
  80. }
  81. }
  82. }
  83. ans[l]=;
  84. for (int i=; i<=f[p].len; i++)
  85. {
  86. int x=f[p].st[i];
  87. inc(ans[l],f[p].c[x]);
  88. }
  89. ans[l]=(m-ans[l]+mo)%mo;
  90. ans[l-]=(ans[l-]-ans[l]+mo)%mo;
  91. }
  92. for (int i=; i<=n; i++)
  93. printf("%d\n",ans[i]);
  94. }
  95. }

hdu5079的更多相关文章

随机推荐

  1. vue2.0实现页面刷新时某个input获得focus

    通过自定义指令:

  2. 子查询 做where条件 做 from的临时表 ,做select的一个字段 等

    子查询 做where条件 做 from的临时表 ,做select的一个字段 等

  3. 【题解】Bzoj2125最短路

    处理仙人掌 ---> 首先建立出圆方树.则如果询问的两点 \(lca\) 为圆点,直接计算即可, 若 \(lca\) 为方点,则需要额外判断是走环的哪一侧(此时与两个点在环上的相对位置有关.) ...

  4. display:inline-block带来的问题及解决办法

    在日常工作中,会经常遇到两个或多个元素并排排列的效果,以前会使用float等实现,float虽然方便好用,但是需要清除浮动,有时会带来意想不到的bug 而且在移动端是不推荐使用float的,所以使用d ...

  5. 【BZOJ 3907】网格 组合数学

    大家说他是卡特兰数,其实也不为过,一开始只是用卡特兰数来推这道题,一直没有怼出来,后来发现其实卡特兰数只不过是一种组合数学,我们可以退一步直接用组合数学来解决,这道题运用组合数的思想主要用到补集与几何 ...

  6. 用npm安装express时报proxy的错误的解决方法

    首先要说明一点:当使用npm install <module-name>时安装组件时,安装的目录是cmd的目录+node_modules+组件名 例子如下:假如你现在安装express这个 ...

  7. OWNER:Java配置文件解决方案 使用简介

    这个感觉还是很方便的一个工具.  学习网站是:http://hao.jobbole.com/owner/ 测试步骤: 1.pom <dependency> <groupId>o ...

  8. IE9,IE10 CSS因Mime类型不匹配而被忽略问题 (转)

    写页面的时候在chrome,fireforks等页面上显示正常,但是换成IE9,IE10之后就完全没有样式了,报错信息是CSS 因 Mime 类型不匹配而被忽略,下面与大家分享下这个问题的相关的回答 ...

  9. Python基础(9)三元表达式、列表解析、生成器表达式

    一.三元表达式 三元运算,是对简单的条件语句的缩写.   # if条件语句 if x > f: print(x) else: print(y) # 条件成立左边,不成立右边 x if x > ...

  10. BZOJ 4823: [Cqoi2017]老C的方块

    分析: 我觉得我的网络流白学了...QAQ... 其实数据范围本是无法用网络流跑过去的,然而出题者想让他跑过去,也就跑过去了... 看到题目其实感觉很麻烦,不知道从哪里入手,那么仔细观察所给出的有用信 ...