P5056-[模板]插头dp

正题

题目链接:https://www.luogu.com.cn/problem/P5056


题目大意

n∗mn*mnm的网格,求有多少条回路可以铺满整个棋盘。


解题思路

插头dpdpdp的,写法是按照题解上的写法。

状态用的是括号匹配,然后用了哈希+邻接表(挂表)还有滚动数组优化空间

然后可以看题解学


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int P=133331;
struct node{int to,next;
}a[P*2];
int n,m,o,tot,zx,zy,t[2],bit[25],ls[P],S[2][P],v[25][25];
long long ans,dp[2][P];
char st[25];
void Add(int s,long long v){int x=s%P;for(int i=ls[x];i;i=a[i].next)if(S[o][a[i].to]==s){dp[o][a[i].to]+=v;return;}t[o]++;dp[o][t[o]]=v;S[o][t[o]]=s;a[++tot].to=t[o];a[tot].next=ls[x];ls[x]=tot;return;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%s",st+1);for(int j=1;j<=m;j++)if(st[j]=='.'){v[i][j]=1;zx=i;zy=j;}}for(int i=0;i<=12;i++)bit[i]=(1<<(i<<1));t[o]=1;S[o][1]=0;dp[o][1]=1;for(int i=1;i<=n;i++){for(int j=1;j<=t[o];j++)S[o][j]<<=2;//将右插头移到最左边 for(int j=1;j<=m;j++){o^=1;tot=t[o]=0;memset(ls,0,sizeof(ls));int s,dpl,rpl;long long w;for(int k=1;k<=t[!o];k++){s=S[!o][k];w=dp[!o][k];dpl=(s>>(j<<1))%4;rpl=(s>>(j-1<<1))%4;if(!v[i][j]){//障碍 if(!dpl && !rpl)Add(s,w);//不能有插头 }else if(!dpl && !rpl){//两边都没有插头if(v[i+1][j]&&v[i][j+1])//开一个左上角插头 Add(s+2*bit[j]+bit[j-1],w);} else if(!dpl && rpl){//只有右插头 if(v[i+1][j])Add(s,w);if(v[i][j+1])Add(s-rpl*bit[j-1]+rpl*bit[j],w);}else if(dpl && !rpl){//只有下插头if(v[i+1][j])Add(s-dpl*bit[j]+dpl*bit[j-1],w);if(v[i][j+1])Add(s,w); }else if(dpl==1&&rpl==1){int c=1;for(int p=j+1;p<=m;p++){if((s>>(p<<1))%4==1)c++;if((s>>(p<<1))%4==2)c--;if(!c){Add(s-bit[j]-bit[j-1]-bit[p],w);break;}}}else if(dpl==2&&rpl==2){int c=1;for(int p=j-2;p>=0;p--){if((s>>(p<<1))%4==2)c++;if((s>>(p<<1))%4==1)c--;if(!c){Add(s-2*bit[j]-2*bit[j-1]+bit[p],w);break;}}}else if(dpl==1&&rpl==2)Add(s-2*bit[j-1]-bit[j],w);else if(dpl==2&&rpl==1)if(i==zx&&j==zy)ans+=w;}}}printf("%lld\n",ans);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318827.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客题霸 [用两个栈实现队列] C++题解/答案

题目描述 用两个栈来实现一个队列&#xff0c;完成队列的Push和Pop操作。 队列中的元素为int类型。 题解&#xff1a; 我们都知道栈的性质是先进后出&#xff0c;队列是先进先出 我们用两个栈来模拟出队列 可以先用一个栈来存数&#xff0c;当要输出时&#xff0c;最上面的是…

Docker最全教程——从理论到实战(一)

容器是应用走向云端之后必然的发展趋势&#xff0c;因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。本篇教程持续编写了2个星期左右&#xff0c;只是为了大家更好地了解、理解和消化这个技术&#xff0c;能够搭上这波车。你可以关注我们的公众号“magiccode…

二分:路标设置(洛谷)

传送门. 解析 只需二分枚举空旷指数即可 对于单次判断的check函数&#xff0c;可以相当于n个路标把路面分成n1个间隔&#xff0c;而对于每个间隔[l,r]和空旷指数x&#xff08;边界已有路标&#xff09;&#xff0c;所需路标应为&#xff1a; (r-l-1)/x&#xff08;比如[2,5…

2020 ICPC亚洲区域赛(沈阳)F-Kobolds and Catacombs(思维+模拟)

F-Kobolds and Catacombs 考虑每一段&#xff0c;先找到最小的&#xff0c;然后把编号小于它的都化为一组&#xff0c;此时有一个最大值需要把小于最大值的在划分进来&#xff0c;然后又有编号小于它的&#xff0c;于是再把编号小于它的划分为一组&#xff0c;while1 循环一下…

P3190-[HNOI2007]神奇游乐园【插头dp】

正题 题目链接:https://www.luogu.com.cn/problem/P3190 题目大意 n∗mn*mn∗m的网格上有权值&#xff0c;求一条权值和最大的不交回路。 1≤n≤100,1≤m≤61\leq n\leq 100,1\leq m\leq 61≤n≤100,1≤m≤6 解题思路 经典的棋盘形插头dpdpdp&#xff0c;和模板不同的地方是求…

牛客题霸 [最长公共子串]C++题解/答案

牛客题霸 [最长公共子串]C题解/答案 题目描述 给定两个字符串str1和str2,输出两个字符串的最长公共子串&#xff0c;如果最长公共子串为空&#xff0c;输出-1 题解&#xff1a; lcs模板 代码&#xff1a; class Solution { public:/*** longest common substring* param …

二分:[BJWC2008]秦腾与教学评估

洛谷传送门 解析 因为至多有一个单数 假设其位置为k&#xff0c;1-i的累加和为s[i] 则s[1]-s[k-1]全是偶数 s[k]-s[max]全是奇数 答案呈单调性&#xff0c;可以用二分算法 check函数&#xff08;计算前缀和&#xff09;也很容易用O&#xff08;n&#xff09;写出&#xff1a…

微软Azure予力Green Dot客服成就不凡

点击蓝字关注我碧点公司&#xff08;Green Dot&#xff09;是仔细聆听消费者心声&#xff0c;以消费者为导向的金融科技创新公司&#xff0c;致力于为大众带来高效、便捷与体验舒适的个人银行业务。Green Dot创造了预付借记卡产业&#xff0c;也是美国最大的可增值预付借记卡和…

2020 ICPC亚洲区域赛(沈阳)H-The Boomsday Project(双指针+dp)

H-The Boomsday Project Code1 暴力我为人人区间转移 O{N∑qlog⁡N}O\{N\sum q\log N \}O{N∑qlogN} #include<bits/stdc.h> using namespace std; using lllong long; template <class Tint> T rd() {T res0;T fg1;char chgetchar();while(!isdigit(ch)) {if(c…

倍增:st表(模板)(洛谷P3865)

[传送门](https://www.luogu.com.cn/problem/P38 解析 板子题最棒了 用mx[i][j]存储以i为起点&#xff0c;长度为2^j次方的区间内的max 分成前后两段&#xff0c;则可以得到递推式&#xff1a; mx[i][k]max(mx[i][k-1],mx[imi[k-1]][k-1]);而关于初始化&#xff0c;显然&…

首届大湾区 DevOps/微服务秋季分享会圆满落幕!

在科技迅速发展的时代&#xff0c;传统行业积极开展数字化转型以在激烈竞争中脱颖而出&#xff0c;新兴行业不停歇地验证业务模式以找准市场定位&#xff1b;软件与行业变得密不可分&#xff0c;各行各业如何快速响应软件需求&#xff0c;已经成为直接关系到企业核心利益的关键…

牛客题霸 [ 大数加法]C++题解/答案

牛客题霸 [ 大数加法]C题解/答案 题解&#xff1a; 本质就是模拟加法运算 想要让s与t长度统一&#xff0c;不足的部分用0来补充 然后从最后一位开始&#xff0c;两个数相加&#xff0c;同时如果超过10&#xff0c;就把多的部分加到下一位 其实就是我们小学在草稿纸上运算加法…

codeforces1012 B. Chemical table(并查集+思维)

B. Chemical table One of the way to solve this problem is to interprete the cells in 2d matrix as an edge in the bipartite graph, that is a cell (i, j) is an edge between i of the left part and j of the right part. 将行号放一边&#xff0c;列号放一边构造…

P7099-[yLOI2020]灼【数学期望,结论】

正题 题目链接:https://www.luogu.com.cn/problem/P7099 题目大意 给出nnn个坐标轴上的点&#xff0c;qqq次询问从某点出发每次等概率向左或者向右一格求到达某个给出点的期望步数。 保证每个询问点左右都有目标点 1≤n≤105,1≤q≤5106,1≤xi,yi≤1091\leq n\leq 10^5,1\leq…

P4258-[WC2016]挑战NPC【带花树】

正题 题目链接:https://www.luogu.com.cn/problem/P4258 题目大意 给出nnn个球&#xff0c;mmm个篮筐&#xff0c;每个球都可以被放入一些特定的篮筐&#xff0c;每个球都要放&#xff0c;要求球的个数小于等于111的篮筐数量最多。 保证有解&#xff0c;输出方案。 1≤T≤5,1…

.NET Core实战项目之CMS 第五章 入门篇-Dapper的快速入门看这篇就够了

写在前面上篇文章我们讲了如在在实际项目开发中使用Git来进行代码的版本控制&#xff0c;当然介绍的都是比较常用的功能。今天我再带着大家一起熟悉下一个ORM框架Dapper&#xff0c;实例代码的演示编写完成后我会通过Git命令上传到GitHub上&#xff0c;正好大家可以再次熟悉下G…

倍增:喷泉 深度解析(洛谷P7167)

洛谷传送门 解析 什么破题 数据范围来看很明显最多到nlogn 首先&#xff0c;对于样例进行一下分析&#xff1a; 我们可以把它转化为一棵树&#xff1a; 每一个根都有对应的权&#xff0c;给你一个结点和加权和&#xff0c;问能爬到哪里 既然是树&#xff0c;自然要找爸爸…

2021牛客暑期多校训练营3 B-Black and white(思维+最小生成树)

B-Black and white 效仿codeforces1012 B. Chemical table&#xff08;并查集思维&#xff09;&#xff0c;只不过边带权&#xff0c;是的nm个点联通&#xff0c;显然就是求最小生成树。 Code1 Kruskal O(n2log⁡n2)O(n^2\log n^2)O(n2logn2) #include<bits/stdc.h> u…

牛客题霸 [ 实现二叉树先序,中序和后序遍历]C++题解/答案

牛客题霸 [ 实现二叉树先序&#xff0c;中序和后序遍历]C题解/答案 题目描述 分别按照二叉树先序&#xff0c;中序和后序打印所有的节点。 题解&#xff1a; 先序&#xff0c;中序&#xff0c;后序都是按照各自规律的 先序的遍历顺序是中前后 中序是前中后 后序是前后中 这…

P5163-WD与地图【tarjan,整体二分,线段树合并】

正题 题目链接:https://www.luogu.com.cn/problem/P5163 题目大意 给出nnn个点mmm条有向边&#xff0c;点有权值&#xff0c;要求支持操作 删除一条边修改一个点的权值求一个点所在强连通分量中前kkk大权值和 1≤n≤105,1≤m,q≤21051\leq n\leq 10^5,1\leq m,q\leq 2\times…