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的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...
随机推荐
- MR数据生成工具指向目录
mrDataTidy_SaveTwoDays.jar 原始路径 :D:\太原MR数据\一天数据整理 目标路径 : D:\MR现场数据整理\保存两天_整理后数据 例如 当前时间:2017-5-17 10 ...
- 一个python脚本解决安装mq的依赖问题
import tarfile import sys,os from _utils.patrol2 import run_cmd import zipfile def get_version(filen ...
- centos重启报错Umounting file systems:umount:/opt:device is busy
系统重启报错: Umounting file systems:umount:/opt:device is busy 只能硬关机,回想一下最近刚安装了nod32 for linux x64的杀毒软件,开 ...
- JNI详解---从不懂到理解
转载:https://blog.csdn.net/hui12581/article/details/44832651 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 C ...
- bootgrid 刷新保持当前排序
1. 前言 主要是利用了HTHNL5的localStorage技术和用ajax传输一个数组到后台并进行判断.这篇文章是解决一个小需求而来的,主要是用来记录. 2. 代码 JavaScript: var ...
- android 知识点汇总
1.activity 它是 android 应用程序的基本功能单元.一个Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,例如拨号.拍照.Activity 本身是没有 ...
- Vue项目启动后首页URL带的#该怎么去掉?
修改router的mode为history就可以 const router = new VueRouter({mode: 'history', routes: [...]}) 实际修改后需要注意修改a ...
- tcpdump使用示例
前言 这段时间一直在研究kubernetes当中的网络, 包括通过keepalived来实现VIP的高可用时常常不得不排查一些网络方面的问题, 在这里顺道梳理一下tcpdump的使用姿势, 若有写的不 ...
- laravel console - 自定义命令
在改造一个支付流程,新的流程加入了一个新的数据表字段,但是这个新的字段需要通过计算来填充,所以为了兼容历史数据,必须将已有的数据行重新计算一遍该字段. 这时使用 laravel console 命令就 ...
- js面向对象 下
// 声明对象的方法 一 (通过常量直接赋值) var xiaoming = {//声明一个对象(直接通过一个常量xiaoming用{}赋值的方式声明) name: '小明', //对象的一个属性 ...