2331: [SCOI2011]地板 插头DP
国际惯例的题面:
十分显然的插头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的更多相关文章
- bzoj 2331: [SCOI2011]地板 插头DP
2331: [SCOI2011]地板 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 541 Solved: 239[Submit][Status] D ...
- 【BZOJ】2331: [SCOI2011]地板 插头DP
[题意]给定n*m的地板,有一些障碍格,要求用L型的方块不重不漏填满的方案数.L型方块是从一个方格向任意两个相邻方向延伸的方块,不能不延伸.n*m<=100. [算法]插头DP [题解]状态0表 ...
- BZOJ 2331 [SCOI2011]地板 ——插头DP
[题目分析] 经典题目,插头DP. switch 套 switch 代码瞬间清爽了. [代码] #include <cstdio> #include <cstring> #in ...
- 【BZOJ2331】[SCOI2011]地板 插头DP
[BZOJ2331][SCOI2011]地板 Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里 ...
- [SCOI2011][bzoj2331] 地板 [插头dp]
题面: 传送门 思路: 插头dp基础教程 这个L形......第一眼看上去真的是丧病啊 但是仔细想想,实际上也就是拿一堆路径铺满一个棋盘,这个路径还是有限制的 那还有什么好说的,插头dp上啊[雾] 首 ...
- bzoj:2331: [SCOI2011]地板
Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板.现在小L想知道,用 ...
- 【BZOJ】2331: [SCOI2011]地板
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2331 一眼插头DP... 考虑一个L形的东西,要构成它可以划分为两个阶段,即当前线段是拐了 ...
- bzoj 2331: [SCOI2011]地板【插头dp】
一开始设计了四种状态,多了一种已经拐弯但是长度为0的情况,后来发现不用,设012表示没插头,没拐弯的插头,拐了弯的插头,然后转移的话12,21,22都不合法,剩下的转移脑补一下即可,ans只能在11, ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...
随机推荐
- c# 创建项目时提示:未能正确加载“microsoft.data.entity.design.bootstrappackage
vs 2005 ,vs 2008, vs 2010,安装后有时出现这个错误(我的机器装的x64的win7),很烦人.找了很多地方都不能解决.其实说起来还是开发国家牛,轻易就解决了这个问题.其实出现这个 ...
- springboot学习笔记-6 springboot整合RabbitMQ
一 RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件.这些软件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿 ...
- 【vim】缩写 :ab [缩写] [要替换的文字]
一个很可能是最令人印象深刻的窍门是你可以在 Vim 中定义缩写,它可以实时地把你输入的东西替换为另外的东西.语法格式如下: :ab [缩写] [要替换的文字] 一个通用的例子是: :ab asap a ...
- H3C SNMP OID
有两种mib-style [1]老些的设备 cpu 使用率OID: .1.3.6.1.4.1.25506.2.6.1.1.1.1.6.slot 内存使用率OID: .1.3.6.1.4.1.2550 ...
- Python poll IO多路复用
一.poll介绍 poll本质上和select没有区别,只是没有了最大连接数(linux上默认1024个)的限制,原因是它基于链表存储的. 本人的另一篇博客讲了 python select : ht ...
- Centos socket TCP代码
一.功能描述: 能够在Centos中创建TCP socket,实现Client给Server发送消息,Server能够Client发送消息. 二.代码如下: ①client代码: #include & ...
- Android通讯:通话
Android通讯之通话功能的实现: 在Android中,android.telephony.TelephonyManager对象是开发者获取当前通话网络相关信息的窗口,通过TelephonyMana ...
- Day5-----------------vi编辑器
1.操作模式 1).命令行模式 2).编辑模式 3).扩展模式 2.命令行模式 1).删除与复制 dd 删除光标所在行 ndd 删除光标向下n行 yy 复制光标所在行 nyy 复制光标乡下n行 2). ...
- python3内存存储几种数据类型对差异
列表,元组,集合,字典几种数据类型差异 列表: list=[0,1,'a'] 元组:list=(0,1,'a') 集合 :list=[0,1,'a'] 字典:list={name:'tom',age: ...
- Mess it up!搞乱代码
Mess it up! 作者: Laruence( ) 本文地址: http://www.laruence.com/2009/01/07/656.html 转载请注明出处 恩,这段代码还能再乱点, ...