【题目分析】

经典题目,插头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. 9.18 New Start

    好久没上cnblogs,今天提示我说园龄已经2年1个月了.今天就用一个日记的形式开始第一篇博客吧.我以后比较精髓的文章就放在cnblogs,csdn博客也继续会更新,不过也会慢慢提高文章质量. 今天是 ...

  2. Servlet The Request

    The Request HTTP Protocol Parameters 所有的HTTP Protocol Parameters都会放在一个Map中, 可以通过getParameterMap得到. 对 ...

  3. leetcode_1033. Moving Stones Until Consecutive

    https://leetcode.com/problems/moving-stones-until-consecutive/ 题意:给定3个点,每次从两个端点(位置最小或位置最大)中挑选一个点进行移动 ...

  4. Bootstrap 网页乱码

    问题:今天早上在实践bootstrap的时候,用EditPlus写代码,标签中包含了中文.在浏览器解析的时候中文部分生成的乱码.但是网页部分已经声明了使用utf-8的编码方式. 解决:网页字体正常显示 ...

  5. shell脚本,检查给出的字符串是否为回文

    [root@localhost wyb]# .sh #!/bin/bash #检查给出的字符串是否为回文 read -p "Please input a String:" numb ...

  6. C# 使用Epplus导出Excel [1]:导出固定列数据

    C# 使用Epplus导出Excel [1]:导出固定列数据 C# 使用Epplus导出Excel [2]:导出动态列数据 C# 使用Epplus导出Excel [3]:合并列连续相同数据 C# 使用 ...

  7. js最高效的数组去重方法

    var arr=[1,2,33,2,4,5,33,5,7,8,1,3];var result=[];var temp={};for( var i=0;i<arr.length;i++){ if( ...

  8. 【动态规划】bzoj1044: [HAOI2008]木棍分割

    需要滚动优化或者short int卡空间 Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍 ...

  9. [LUOGU] P1063 能量项链

    题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定 ...

  10. Linux下安装以及使用MySQL数据库

    1.官网下载mysql数据库:https://dev.mysql.com/downloads/mysql/ 2.linux 下可直接下载:wget https://cdn.mysql.com//Dow ...