BZOJ2808 : 那些年我们画格子

若$\min(n,m)=1$,那么设$f[i][j][k]$表示考虑前$i$个格子,改变了$j$次颜色,$i$的颜色为$k$的方案数,直接转移即可。

否则$\min(n,m)\geq 2$,那么有解当且仅当第一二行重复得到整个图案或者第一二列重复得到整个图案。

假设是第一二行重复:

那么可以设$g[i][j][x][y]$表示考虑前$i$列,改变了$j$次颜色,第一行第$j$列颜色为$x$,第二行第$j$列颜色为$y$的方案数。

预处理出每种颜色会增加几次改变,然后转移即可。

若是第一二列重复,只需要转置这个矩阵,即可转化为第一二行重复。

这其中多算的是第一二行重复同时第一二列重复的情况,此时直接枚举左上角$4$个格子的颜色然后检验即可。

时间复杂度$O(n(m+k))$。

#include<cstdio>
const int N=105,P=1000000007;
int n,m,K,S,o,i,j,k,x,y,t,A,B,f[2][N*N][5],g[2][N*N][4][4],w[4][4],ans;char a[N][N],b[N][N];
inline int getid(char x){
  if(x==‘G‘)return 0;
  if(x==‘B‘)return 1;
  if(x==‘R‘)return 2;
  return 3;
}
inline void up(int&a,int b){a=a+b<P?a+b:a+b-P;}
void check(int S){
  b[1][1]=S&3;
  b[1][2]=S>>2&3;
  b[2][1]=S>>4&3;
  b[2][2]=S>>6;
  for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(i>2||j>2)b[i][j]=b[i&1?1:2][j&1?1:2];
  for(t=0,i=1;i<=n;i++)for(j=1;j<=m;j++)if(a[i][j]!=b[i][j])t++;
  if(t>K)return;
  for(i=1;i<=n;i++)for(j=1;j<=m;j++)
    for(x=-1;x<=1;x++)if(i+x>=1&&i+x<=n)for(y=-1;y<=1;y++)if((x||y)&&j+y>=1&&j+y<=m)
      if(b[i][j]==b[i+x][j+y])return;
  ans++;
}
inline void getw(int x,int m){
  for(int A=0;A<4;A++)for(int B=0;B<4;B++){
    w[A][B]=0;
    for(int i=1;i<=m;i++){
      int j=i&1?A:B;
      if(j!=b[x][i])w[A][B]++;
    }
  }
}
void solve(int n,int m){
  getw(1,m);
  for(j=0;j<=K;j++)for(x=0;x<4;x++)for(y=0;y<4;y++)g[0][j][x][y]=0;
  for(o=x=0;x<4;x++)for(y=0;y<4;y++)if(w[x][y]<=K&&x!=y)g[0][w[x][y]][x][y]=1;
  for(i=2;i<=n;i++){
    getw(i,m);
    for(j=0;j<=K;j++)for(x=0;x<4;x++)for(y=0;y<4;y++)g[o^1][j][x][y]=0;
    for(j=0;j<=K;j++)for(x=0;x<4;x++)for(y=0;y<4;y++)if(g[o][j][x][y])
      for(k=0;k<4;k++)if(k!=x&&k!=y){
        t=6-x-y-k;
        if(j+w[k][t]<=K){
          up(g[o^1][j+w[k][t]][k][t],g[o][j][x][y]);
        }
      }
    o^=1;
  }
  for(j=0;j<=K;j++)for(x=0;x<4;x++)for(y=0;y<4;y++)up(ans,g[o][j][x][y]);
}
int main(){
  scanf("%d%d%d",&n,&m,&K);
  for(i=1;i<=n;i++){
    scanf("%s",a[i]+1);
    for(j=1;j<=m;j++)a[i][j]=getid(a[i][j]);
  }
  if(n==1||m==1){
    for(f[0][0][4]=i=1;i<=n;i++)for(j=1;j<=m;j++){
      for(k=0;k<=K;k++)for(x=0;x<5;x++)f[o^1][k][x]=0;
      for(k=0;k<=K;k++)for(x=0;x<5;x++)if(f[o][k][x])for(y=0;y<4;y++)if(y!=x)up(f[o^1][k+(y!=a[i][j])][y],f[o][k][x]);
      o^=1;
    }
    for(i=0;i<=K;i++)for(j=0;j<4;j++)up(ans,f[o][i][j]);
  }else{
    for(S=0;S<1<<8;S++)check(S);
    ans=(P-ans)%P;
    for(i=1;i<=n;i++)for(j=1;j<=m;j++)b[i][j]=a[i][j];
    solve(n,m);
    for(i=1;i<=n;i++)for(j=1;j<=m;j++)b[j][i]=a[i][j];
    solve(m,n);
  }
  return printf("%d",ans),0;
}

  

时间: 2024-11-03 03:31:45

BZOJ2808 : 那些年我们画格子的相关文章

第十九天(小格子)

1 <head> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 3 <title>无标题文档</title> 4 <style type="text/css"> 5 * 6 { 7 margin:0px; 8 padding:0px;} 9 </style> 10 </he

随机三角形平铺布局算法(iOS实现)

你是否已经看够iOS里默认给出的那些方方正正的块状和规规矩矩的陈列? 本篇给出一种随机三角形平铺布局的算法设计和实现.这种布局在规矩与随机之间做了折中,使其看上去有新鲜感又不会很乱. 本次实现重点在于布局算法的设计和实现,可以改变颜色或者添加图片. 最新源代码下载地址:https://github.com/duzixi/Varied-Layouts(持续维护,欢迎互粉) 博文首发地址:http://blog.csdn.net/duzixi 布局生成效果如下:         核心算法设计以及代码

借鉴一些关于js框架的东西

八款Js框架介绍及比较,Dojo .Scriptaculous .Prototype .yui-ext .Jquery .Mochikit.mootools .moo.fx,componentartui (转载) Extjs 与 JQuery 1.Turbomail(www.turbomail.org)下一版本决定用Extjs + jquery 开发.2.JQuery 提供了方便的对网页元素操作方法,但不提供基本控件,如:Tab,Grid,Muen 等,Extjs 是一套   完整的控件库,Ex

八、Quartz2D

1.基本图形绘制 >>绘图步骤 > 获取图形上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); > 拼接路径 // 设置起点 CGContextMoveToPoint(ctx, 10, 10); // 设置终点 CGContextMoveToPoint(ctx, 100, 100); CGContextAddLineToPoint该方法会将当前图形上下文的起点链接一条线到指定点 CGContextAddLineToPoint(

个人项目----词频统计WEB(部分功能)

需求分析 1.使用web上传txt文件,对上传的txt进行词频统计. 2.将统计后的结果输出到web页面,力求界面优美. 3.在界面上展示所给url的文章词频统计,力求界面优美. 3.将每个单词同四.六级词库进行比对,统计所传txt文件中四.六级单词涵盖率. 4.在3的基础上,展示文章中前10%单词中的覆盖百分比,词频前50%单词.词频前80%单词的覆盖百分比. 由于能力有限,学习了很久,到目前为止之完成了第一个功能,并对结果进行了输出,界面部分还有待学习. 代码实现 创建了两个JSP界面,up

Ax 导出EXCEL给范围内的每个单元格加边框

1. 首先在Class\SysExcelRange加画边框的方法 思路用EXCEL录宏的功能得到给一批单元格画格子的VBA代码,在AX将对象转为COM对象,基本VBA代码也能装为AX内能用的内容. public void BorderLine() { Com borders; ComVariant LineStyle,Weight,ColorIndex; int xlEdgeBottom = 9; int xlContinuous = 1; int xlThin = 2; int xlAutom

BFS迷宫问题

1 #include<graphics.h> 2 #include<stdlib.h> 3 #include<conio.h> 4 #include<time.h> 5 #include<vector> 6 #include<queue> 7 #include<stack> 8 #include<iostream> 9 #include <algorithm> 10 11 using namespa

【iOS】随机三角瓷砖布局算法

你已经看够iOS鉴于这些默认的正方形块,整齐地显示? 本篇给出一个随机算法设计的三角布局的瓷砖和实施. 这样的规则,并提出妥协随机排列间.它看起来很凌乱,不会有一个新事物. 重点是设计和实施,以实现布局算法,能够改变颜色或者加入图片. 最新源码下载地址:https://github.com/duzixi/Varied-Layouts(持续维护.欢迎互粉) 博文首发地址:http://blog.csdn.net/duzixi 布局生成效果例如以下: watermark/2/text/aHR0cDo

调用CImg库显示WAV格式音频波形

在做傅里叶变换和小波变换时经常要通过显示波形来检验算法,但通过visual studio之类显示波形又显得麻烦,而且不能跨平台. CImg是一个跨平台的C++的图像处理库,提供的图像处理等功能十分强大,而且加入项目中十分轻便,只需将头文件包含在项目中即可,十分轻便. 可自行到http://www.cimg.eu/下载 利用它来在linux.Mac OS X中显示波形,再合适不过了,下面是音频波形显示的代码. 主函数 main.cpp #include <iostream> #include &