【题目分析】

经典题目,插头DP。

switch 套 switch 代码瞬间清爽了。

【代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define maxn 400005
const int md=20110520;
int dp[2][maxn],a[101][101],n,m,fac[15],tot,b[15];
char s[105];
void print(int x){F(i,0,m) printf("%d",(x%fac[i+1])/fac[i]);}
int main()
{
scanf("%d%d",&n,&m);
F(i,0,n-1){scanf("%s",s);F(j,0,m-1)a[i][j]=s[j]=='*'?1:0;}
if (m>n){F(i,0,m-1)F(j,i+1,m-1)swap(a[i][j],a[j][i]);swap(m,n);}
// F(i,0,n-1){F(j,0,m-1)printf("%d ",a[i][j]);printf("\n");}
fac[0]=1;F(i,1,13)fac[i]=fac[i-1]*3;tot=fac[m+1]-1;
int now=1,pre=0;
memset(dp[now],0,sizeof dp[now]);
dp[now][0]=1;
F(i,0,n-1) F(j,0,m-1)
{ if (a[i][j])
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("now is "); print(s); printf(" \n");
int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
if (!tmp1&&!tmp2)
{
(dp[now][s]+=dp[pre][s])%=md;
// printf(" to "); print(s); printf("\n");
}
}
}
else
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("now is "); print(s); printf(" \n");
int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
switch(tmp1)
{
case 0:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]+2*fac[j+1]); printf("\n");
(dp[now][tmp+2*fac[j]+2*fac[j+1]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j]); printf("\n");
(dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j+1]); printf("\n");
(dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
break;
case 1:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+fac[j]); printf("\n");
(dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+2*fac[j+1]); printf("\n");
(dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
break;
case 2:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
break;
}
break;
case 1:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j+1]); printf("\n");
(dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
break;
case 1:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
break;
case 2:
break;
}
break;
case 2:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
break;
case 1:
break;
case 2:
break;
}
break;
}
}
}
if (j==m-1)
{
// printf("On The last of road\n");
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("End with "); print(s);
int tmp=s,tmp1=(s%fac[m+1])/fac[m];
if (tmp1) {continue;}
tmp*=3;
// printf(" can become "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
}
}
}
printf("%d\n",dp[now][0]);
}

  

BZOJ 2331 [SCOI2011]地板 ——插头DP的更多相关文章

  1. bzoj 2331: [SCOI2011]地板 插头DP

    2331: [SCOI2011]地板 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 541  Solved: 239[Submit][Status] D ...

  2. 【BZOJ】2331: [SCOI2011]地板 插头DP

    [题意]给定n*m的地板,有一些障碍格,要求用L型的方块不重不漏填满的方案数.L型方块是从一个方格向任意两个相邻方向延伸的方块,不能不延伸.n*m<=100. [算法]插头DP [题解]状态0表 ...

  3. 2331: [SCOI2011]地板 插头DP

    国际惯例的题面:十分显然的插头DP.由于R*C<=100,所以min(R,C)<=10,然后就可以愉悦地状压啦.我们用三进制状压,0表示没有插头,1表示有一个必须延伸至少一格且拐弯的插头, ...

  4. 【BZOJ2331】[SCOI2011]地板 插头DP

    [BZOJ2331][SCOI2011]地板 Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里 ...

  5. bzoj:2331: [SCOI2011]地板

    Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板.现在小L想知道,用 ...

  6. bzoj 2331: [SCOI2011]地板【插头dp】

    一开始设计了四种状态,多了一种已经拐弯但是长度为0的情况,后来发现不用,设012表示没插头,没拐弯的插头,拐了弯的插头,然后转移的话12,21,22都不合法,剩下的转移脑补一下即可,ans只能在11, ...

  7. 【BZOJ】2331: [SCOI2011]地板

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2331 一眼插头DP... 考虑一个L形的东西,要构成它可以划分为两个阶段,即当前线段是拐了 ...

  8. [SCOI2011][bzoj2331] 地板 [插头dp]

    题面: 传送门 思路: 插头dp基础教程 这个L形......第一眼看上去真的是丧病啊 但是仔细想想,实际上也就是拿一堆路径铺满一个棋盘,这个路径还是有限制的 那还有什么好说的,插头dp上啊[雾] 首 ...

  9. BZOJ.1210.[HNOI2004]邮递员(插头DP Hash 高精)

    BZOJ 洛谷 http://www.cnblogs.com/LadyLex/p/7326874.html 插头DP.\(m+1\)个插头的状态需要用三进制表示:\(0\)表示无插头,\(1\)表示是 ...

随机推荐

  1. Objective-C Fast Enumeration

    Fast enumeration is an Objective-C's feature that helps in enumerating through a collection. So in o ...

  2. 2017“编程之美”终章:AI之战勇者为王

    编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...

  3. 覆盖alert对话框-自制Jquery.alert插件

    Javascript 代码: (function ($) { 'use strict'; window.alert = $.alert = function (msg) { var defaultOp ...

  4. ftp - Internet 文件传输程序 (file transfer program)

    概述 (SYNOPSIS) ftp [-pinegvd ] [host ] pftp [-inegvd ] [host ] 说明 (DESCRIPTION) 用户通过 Ftp 这个程序来使用 Inte ...

  5. Centos7 安装python3.5.3

    使用root用户安装:切换到root用户 su 回车,然后输入密码,切换到root用户. 新建一个脚本,如installPython.sh #!/bin/bash yum -y install zli ...

  6. nuxt 初接触

    对于nuxt服务端渲染让人动心的是不会再想vue一样去定义无数的路由了这一点是挺爽的!!! 先直接晒张图 在api这块增加了一个fetch方法   它会在组件每次加载前被调用(即在服务端或切换至目标路 ...

  7. robotframe处理日志中文问题

    unicode('${addr1.text}',"utf-8")

  8. python之for (循环)

    格式: for 循环 for i in s: print(i) # for 关键字 # i 变量 # in 关键字 # s 可迭代对象 int - bool pass和- # for a in &qu ...

  9. 设置section的距离

    在ios7中使用group类型的tableview时,第一个section距离navigationbar的距离很大,不符合这边的设计图.使用 myTableView . sectionHeaderHe ...

  10. LeetCode 朋友圈

    班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋友的集合. ...