BZOJ3336: Uva10572 Black and White(插头Dp)
解题思路:
分类讨论即可。
代码(懒得删Debug了):
- #include<map>
- #include<cstdio>
- #include<vector>
- #include<cstring>
- #include<algorithm>
- #define black '#'
- #define white 'o'
- #define BLACK_AND_WHITE int main(){/*freopen("a.in","r",stdin);*/scanf("%d",&T);while(T--)Black_and_White();return 0;}
- typedef long long lnt;
- typedef unsigned int uit;
- typedef unsigned long long unt;
- int T;
- int n,m;
- int p,q;
- unt ans=;
- int mp[][];
- char cmd[];
- uit code[];
- uit tod[];
- int clor[];
- bool col[];
- std::map<unt,unt>dp[],ooo;
- void minpress(uit *cd)
- {
- int cnt=;
- memset(clor,,sizeof(clor));
- for(int i=;i<=m;i++)
- {
- if(!clor[cd[i]])
- clor[cd[i]]=++cnt;
- cd[i]=clor[cd[i]];
- }
- return ;
- }
- unt compress(uit *cd,int hc)
- {
- unt ret=hc;
- minpress(cd);
- for(int i=;i<=m;i++)
- ret=ret*10ull+cd[i];
- return ret;
- }
- void decompress(uit *cd,bool *cl,unt sit)
- {
- for(int i=m;i>=;i--)
- {
- cd[i]=sit%10ull;
- sit/=10ull;
- }
- cl[]=sit;
- for(int i=;i<=m;i++)
- if(cd[i]!=cd[i-])
- cl[i]=-cl[i-];
- else
- cl[i]=cl[i-];
- return ;
- }
- bool banned(int l,int r,int pos,uit *cd)
- {
- for(int i=;i<l;i++)
- if(cd[i]==cd[pos-])
- return false;
- for(int i=r-;i<=m;i++)
- if(cd[i]==cd[pos-])
- return false;
- return true;
- }
- void update(int cmd,unt tmp,unt v)
- {
- if(dp[cmd].find(tmp)==dp[cmd].end())
- dp[cmd][tmp]=v;
- else
- dp[cmd][tmp]+=v;
- return ;
- }
- void Insert(int ii,int jj,unt s,unt v,bool b)
- {
- decompress(code,col,s);
- int lu,uu,ll,hc=col[];
- /* printf("%d ",hc);
- for(int k=0;k<=m;k++)
- printf("%d ",code[k]);
- printf("%d",v);
- /* puts("");/*
- for(int i=0;i<=m;i++)
- printf("%d ",col[i]);*/
- uu=col[jj]^b;
- lu=col[jj-]^b;
- ll=col[jj-]^b;
- /* printf(uu?"b":"w");
- printf(lu?"b":"w");
- printf(ll?"b":"w");*/
- // puts("");
- uit maxs=;
- for(int i=;i<=m;i++)
- maxs=std::max(maxs,code[i]);
- for(int i=;i<=m;i++)
- tod[i]=code[i];
- if(ll)
- {
- if(lu)
- {
- if(uu)
- tod[jj-]=maxs+;
- else
- tod[jj-]=tod[jj];
- }else{
- if(uu)
- {
- if(ii==n&&jj==m)
- return ;
- if(banned(jj-,jj+,jj+,tod))
- return ;
- //printf("+1\n");
- tod[jj-]=maxs+;
- }else
- tod[jj-]=tod[jj];
- }
- }else{
- if(lu)
- {
- if(uu)
- {
- if(banned(jj-,jj+,jj+,tod))
- {
- if(ii!=n||(jj!=m&&jj!=m-))return ;
- for(int i=;i<jj-;i++)
- if(col[i]==col[jj])
- return ;
- for(int i=jj+;i<=m;i++)
- if(col[i]==col[jj])
- return ;
- }
- tod[jj-]=tod[jj-];
- }else{
- tod[jj]=tod[jj-]=tod[jj-];
- for(int i=;i<=m;i++)
- {
- if(code[i]==code[jj]||code[i]==code[jj-])
- tod[i]=tod[jj-];
- }
- }
- }else{
- if(uu)
- {
- if(banned(jj-,jj+,jj+,tod))
- {
- if(ii!=n||(jj!=m&&jj!=m-))return ;
- for(int i=;i<jj-;i++)
- if(col[i]==col[jj])
- return ;
- for(int i=jj+;i<=m;i++)
- if(col[i]==col[jj])
- return ;
- }
- tod[jj-]=tod[jj-];
- }else return ;
- }
- }
- unt tmp=compress(tod,hc);
- if(ii==n&&jj==m)
- {
- int cnt=;
- decompress(code,col,tmp);
- memset(clor,,sizeof(clor));
- for(int i=;i<=m;i++)
- if(!clor[code[i]])
- clor[code[i]]=++cnt;
- if(cnt<=)
- ans+=v;
- return ;
- }
- update(p,tmp,v);
- return ;
- }
- void Insert(int i,unt s,unt v,bool b)
- {
- decompress(code,col,s);
- int uu,hc=col[];
- /* printf("%d ",hc);
- for(int k=0;k<=m;k++)
- printf("%d ",code[k]);
- printf("%d ",v);
- puts("");*/
- for(int i=;i<=m;i++)
- tod[i]=code[i];
- uu=col[]^b;
- if(uu)
- {
- if(banned(,,,tod))
- return ;
- code[]=;
- hc=b;
- }else
- code[]=code[];
- unt tmp=compress(code,hc);
- if(i==n&&m==)
- {
- int cnt=;
- decompress(code,col,tmp);
- memset(clor,,sizeof(clor));
- for(int ii=;ii<=m;ii++)
- if(!clor[code[ii]])
- clor[code[ii]]=++cnt;
- if(cnt<=)
- ans+=v;
- }
- update(p,tmp,v);
- return ;
- }
- unt move(unt x)
- {
- decompress(code,col,x);
- int hc=col[];
- for(int i=m;i;i--)
- code[i]=code[i-];
- return compress(code,hc);
- }
- void Move(void)
- {
- ooo.clear();
- for(std::map<unt,unt>::iterator i=dp[p].begin();i!=dp[p].end();i++)
- ooo[i->first]=i->second;
- dp[p].clear();
- for(std::map<unt,unt>::iterator i=ooo.begin();i!=ooo.end();i++)
- {
- update(p,move(i->first),i->second);
- // printf("%I64u %I64u\n",move(i->first),i->second);
- }
- return ;
- }
- void Black_and_White(void)
- {
- dp[].clear();
- dp[].clear();
- ans=;
- p=,q=;
- memset(mp,,sizeof(mp));
- memset(code,,sizeof(code));
- memset(clor,,sizeof(clor));
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;i++)
- {
- scanf("%s",cmd+);
- for(int j=;j<=m;j++)
- {
- if(cmd[j]==white)
- mp[i][j]=-;
- else if(cmd[j]==black)
- mp[i][j]=;
- else
- mp[i][j]=;
- }
- }
- if(n==&&m==)
- {
- if(mp[][])
- puts("");
- else
- puts("");
- return ;
- }
- for(int i=;i<(<<m);i++)
- {
- int cnt=;
- code[]=code[]=;
- bool ban=false;
- for(int j=;j<=m;j++)
- {
- if(mp[][j]==&&((i&(<<(j-)))==))ban=true;
- if(mp[][j]==-&&(i&(<<(j-)))) ban=true;
- if(ban)break;
- }
- if(ban)
- continue;
- for(int j=;j<=m;j++)
- {
- if((bool)(i&(<<(j-)))^(bool)(i&(<<(j-))))
- cnt++;
- code[j]=cnt;
- }
- int co=i&;
- // printf("%d ",co);
- // puts("");
- unt s=compress(code,co);
- // printf("%d\n",s);
- update(p,s,);
- }
- for(int i=;i<=n;i++)
- {
- // puts("\n~~~~~~~~~~~~~~~~~~~~~~");
- std::swap(p,q);
- dp[p].clear();
- for(std::map<unt,unt>::iterator k=dp[q].begin();k!=dp[q].end();k++)
- {
- unt s=k->first;
- unt v=k->second;
- if(mp[i][]!=)
- Insert(i,s,v,);
- if(mp[i][]!=-)
- Insert(i,s,v,);
- }
- // puts("_________________________");
- for(int j=;j<=m;j++)
- {
- // puts("\n~~~~~~~~~~~~~~~~~~~~~~");
- std::swap(p,q);
- dp[p].clear();
- for(std::map<unt,unt>::iterator k=dp[q].begin();k!=dp[q].end();k++)
- {
- unt s=k->first;
- unt v=k->second;
- if(mp[i][j]!=)
- Insert(i,j,s,v,);
- if(mp[i][j]!=-)
- Insert(i,j,s,v,);
- }
- // puts("_________________________");
- }
- // puts("%d");
- Move();
- }
- printf("%llu\n",ans);
- return ;
- }BLACK_AND_WHITE
BZOJ3336: Uva10572 Black and White(插头Dp)的更多相关文章
- BZOJ 3336 Black and White (插头DP)
题目大意: 给你一个n×m的网格,有一些格子已经被涂上了白色或者黑色,让你用黑色或白色填剩下的格子,且填好的网格必须保证: 1.对于任意2×2的子矩阵的4个格子,它们的颜色不能都相同 2.所有黑色的块 ...
- bzoj3336 Uva10572 Black and White
题目描述: 数据范围:2<=n,m<=8 题解: 很明显需要状压.但是怎么压不知道,压什么不知道. 然后从条件下手. 条件1要求黑色在一起白色在一起,记录轮廓线很容易做到. 条件2要求不能 ...
- 插头dp练习
最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...
- 插头dp
插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...
- HDU 4113 Construct the Great Wall(插头dp)
好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...
- HDU 4949 Light(插头dp、位运算)
比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...
- 插头DP专题
建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...
- HDU 1693 Eat the Trees(插头DP)
题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...
随机推荐
- Boom
紧急事件!战场内被敌军埋放了n枚炸弹! 我军情报部门通过技术手段,掌握了这些炸弹的信息.这些炸弹很特殊,每枚炸弹的波及区域是一个矩形.第i枚炸弹的波及区域是以点(xi1,yi1)为左下角,点(xi2, ...
- Audio / Video Playback
For Developers > Design Documents > Audio / Video Playback Interested in helping out? Ch ...
- Linux 图形文件压缩/解压缩实用程序,归档管理器。
1.ArkArk是KDE桌面环境默认的归档管理器,支持插件设置,允许你创建一个压缩包,查看压缩文件的内容,解压压缩包的内容到你所选定的目录.它能处理多种格式,包括 tar.gzip.bzip2.zip ...
- 并查集 (Union Find ) P - The Suspects
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized ...
- Timestamp 转 date
Timestamp startTime = new Timestamp(new Date().getTime());
- 搭建Lvs负载均衡群集
一.Lvs详解 lvs内核模型 1.模型分析 用户访问的数据可以进入调度器 匹配调度器分配的虚拟IP|IP+端口(路由走向) 根据调度器的算法确定匹配的服务器 2.调度条件:基于IP.基于端口.基于内 ...
- BZOJ 1305 二分+网络流
思路: 建图我根本没有想到啊--. (我是不会告诉你我借鉴了一下题解的思路) 把每个人拆成喜欢的和不喜欢的点 男 喜欢 向 男 不喜欢 连 边权为k的边 如果男喜欢女 那么 男喜欢向 女喜欢 连 1 ...
- request获取各种路径总结、页面跳转总结。
页面跳转总结 JSP中response.sendRedirect()与request.getRequestDispatcher().forward(request,response)这两个对象都可以使 ...
- Flex之登录界面
制作登录框界面 环境搭建:MyEclipse 6.5+Flex Builder 3 Plug-in <?xml version="1.0" encoding="ut ...
- dedecms关键词维护里面字数多的词优先字数少的词的解决办法
织梦后台的关键词维护默认的情况是字数少的词优先于字数多的词,比如我们有两个这样的词:创业.创业方向,第二个词包含了第一个词,在文章中如果出现“创业方向”这个词,默认情况下只会给创业两个字添加关键词超链 ...