国际惯例的题面:

十分显然的插头DP。由于R*C<=100,所以min(R,C)<=10,然后就可以愉悦地状压啦。
我们用三进制状压,0表示没有插头,1表示有一个必须延伸至少一格且拐弯的插头,2表示有一个必须延伸一格且不可以拐弯的插头。
转移的话就十分显然了。
00->22,表示用这个格子作为开始的拐角。
00->10,表示用这个格子向下延伸。
00->01,表示用这个格子向右延伸。
01->10,表示这个格子连接上下。
01->02,表示在这个格子作为中间的拐角。
02->20,表示这个格子连接上下。
02->00,表示这个格子作为某个地板的终点。
10->01,表示这个格子连接左右。
10->20,表示在这个格子作为中间的拐角。
11->00,表示这个格子作为结束的拐角。
20->00,表示这个格子作为某个地板的终点。
20->02,表示这个格子连接左右。
(插头DP的本质就是分类讨论,所以麻烦也没办法,想明白就很容易了)
然后就是实现了。我是用unordered_map存储状态,同时先找到第一个可以放东西的位置开始DP,统计答案的时候统计第n+1行没有插头的状态。

代码:

 #pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<tr1/unordered_map>
using namespace std;
using namespace tr1;
const int maxn=1e2+1e2;
const int mod=; int sta[maxn],nxt[maxn];
char in[maxn][maxn]; // in == 1 means empty .
int n,m,cur,fx,fy;
unordered_map<int,int> f[]; inline void unzip(int* sta,int ss) {
for(int i=m+;i;i--) sta[i] = ss % , ss /= ;
}
inline int zip(int* sta) {
int ret = ;
for(int i=;i<=m+;i++) ret = ret * + sta[i];
return ret;
} inline void core_trans(unordered_map<int,int> &dst,int x,int y,int add) {
memcpy(nxt,sta,sizeof(int)*(m+));
if( !in[x][y] ) { // not empty .
if( sta[y] == && sta[y+] == ) ( dst[zip(nxt)] += add ) %= mod;
return;
}
if( sta[y] == ) {
if( sta[y+] == ) {
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
} else if( sta[y+] == ) {
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
} else if( sta[y+] == ) {
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
}
} else if( sta[y] == ) {
if( sta[y+] == ) {
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
} else if( sta[y+] == ) nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
} else if( sta[y] == ) {
if( sta[y+] == ) {
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
nxt[y] = , nxt[y+] = , ( dst[zip(nxt)] += add ) %= mod;
}
}
}
inline void trans(const unordered_map<int,int> &sou,unordered_map<int,int> &dst,int x,int y) {
dst.clear();
for(unordered_map<int,int>::const_iterator it=sou.begin();it!=sou.end();it++) if( it->second ) {
unzip(sta,it->first) , core_trans(dst,x,y,it->second);
}
}
inline void transline(const unordered_map<int,int> &sou,unordered_map<int,int> &dst) {
dst.clear();
for(unordered_map<int,int>::const_iterator it=sou.begin();it!=sou.end();it++) if( it->second && ! ( it->first % ) ) {
dst[it->first/] = it->second;
}
} inline void revert() { // make m <= n .
static char tp[maxn][maxn];
memcpy(tp,in,sizeof(in)) , memset(in,,sizeof(in));
for(int i=;i<=n;i++) for(int j=;j<=m;j++) in[j][i] = tp[i][j];
swap(n,m);
} int main() {
scanf("%d%d",&n,&m) , fx = - , fy = -;
for(int i=;i<=n;i++) {
scanf("%s",in[i]+);
for(int j=;j<=m;j++) in[i][j] = in[i][j] == '_';
} if( n < m ) revert();
for(int i=;i<=n&&!~fx;i++) for(int j=;j<=m&&!~fx;j++) if(in[i][j]) fx = i , fy = j;
if( !~fx ) return puts("") , ; // nothing to do .
sta[fy] = , sta[fy+] = , f[cur][zip(sta)] = ;
sta[fy] = , sta[fy+] = , f[cur][zip(sta)] = ;
sta[fy] = sta[fy+] = , f[cur][zip(sta)] = ;
for(int j=fy+;j<=m;j++) trans(f[cur],f[cur^],fx,j) , cur ^= ;
transline(f[cur],f[cur^]) , cur ^= ; for(int i=fx+;i<=n;i++) {
for(int j=;j<=m;j++)
trans(f[cur],f[cur^],i,j) , cur ^= ;
transline(f[cur],f[cur^]) , cur ^= ;
} printf("%d\n",f[cur][]); return ;
}

たいせつなきみのために ぼくにできるいちばんのことは
为了最重要的你 我所能做的最好的事
約束を忘れること君への想い消し去ること
就是忘却与你的约定抹去对你的思念
沈む夕日暮れてく空 夜の帳舞い降りる頃
渐渐归隐大地的夕阳 夜幕降临整个天空 夜的气息轻盈飘落之时
僕は目を閉じて それは闇に溶けるように 滲んで消えた
我闭目去感受 一切就像溶入暗影一样 渗透进去消散无痕了

未来なんていらないよ
未来(明日)什么的已经不需要了吧
君が側にいる過去のままで
因为有你一直陪伴我的往昔(昨日)

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. BZOJ 2331 [SCOI2011]地板 ——插头DP

    [题目分析] 经典题目,插头DP. switch 套 switch 代码瞬间清爽了. [代码] #include <cstdio> #include <cstring> #in ...

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

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

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

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

  6. bzoj:2331: [SCOI2011]地板

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

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

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

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

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

  9. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...

随机推荐

  1. SSD win7优化步骤

    随着固态硬盘价格不断下降,目前固态硬盘也得到了广泛了应用,一些新笔记本以及组装电脑也开始普遍采用固态硬盘平台,超级本就更不用说了,采用固态硬盘已经成标配化,虽然固态硬盘速度很快,但不懂的优化,依然无法 ...

  2. Linux内核驱动基础(一)常用宏定义【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/9427081 一: __init和__initdata  : __exit和__exitdata ...

  3. setfacl报错Operation not supported

    对文件目录setfacl权限设置时报错Operation not supported Google一下,发现是分区acl权限问题 一般情况下(ext4),默认acl支持都是加载的.但如果遇到二般情况, ...

  4. Child Process模块

    目录 exec() execSync() execFile() spawn() fork() send() 参考链接 child_process模块用于新建子进程.子进程的运行结果储存在系统缓存之中( ...

  5. oem 重建

    OracleDBControl启动失败to local from URL=http://your-url.co     方法: emca -deconfig dbcontrol db -repos d ...

  6. Python-JS事件与面向对象操作

    目录一.函数高级 循环绑定: 使用循环绑定会出现的问题及解决方案: 二.面向对象 3.构造函数(ES5) 三.JS选择器 1.getElement系列(最严谨) 2.querySelector系列(最 ...

  7. LoadRunner性能测试入门教程

    javaweb性能测试那些事 一:什么是javaweb性能测试: 二:javaweb性能测试基本流程 三:javaweb性能测试常用指标: 1:响应时间:2-5-8 原则 2:吞吐量 3:资源使用率 ...

  8. samba 设置文件的读写权限

    原文:https://blog.csdn.net/lan120576664/article/details/50396511 打开配置文件 sudo pico /etc/samba/smb.conf ...

  9. poj3468

    #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define ...

  10. Linux学习笔记:使用prompt关闭ftp中mget和mput的确认提醒

    当使用mget和mput上传或下载多个文件时,为了关闭确认提醒,可使用prompt命令. ftp prompt  -- 切换提示 切换交谈式指令(使用mput/mget 时不用每个文件皆询问yes/n ...