P3170-[CQOI2015]标识设计【插头dp】

1|0正题

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


1|1题目大意

给出nm的网格上有一些障碍,要求用三个L形(高宽随意,不能退化成线段/点)覆盖格子且L形之间不能重叠。

求覆盖方案(每个L形相同)

2n,m30


1|2解题思路

一道比模板要简单的插头dp?(当然我依旧不会)

先是考虑插头的状态,每个L形的话,一个还没有涂完的L形可能是右插头或者下插头,因为只有三个所以最多只会有3个下插头,这样的状态数是Cm3的,在5000以内。

把这些状态压缩起来,然后设fx,y,s,k,0/1表示现在dp到格子(x,y),目前下插头状态为s,已经插入了kL形(作为下插头),目前有没有右插头。

转移的话就很简单了,如果下一个格子有障碍那它上面就不能有插头,如果这个格子上面有插头就分为结束这个下插头变为一个右插头或者不结束。
如果这个格子有右插头那么就不能有上插头。
没有这些限制就能够开一个下插头。

需要注意到行尾的时候可能会还有右插头,在最右边加一列障碍就好了。
时间复杂度是O(nmCm3)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=32,M=5100; ll n,m,cnt,f[N][M][4][2]; ll id[N][N][N],pi[M],pj[M],pk[M]; bool v[N][N];char s[N]; void init(){ for(ll i=0;i<=m;i++) for(ll j=i?(i+1):0;j<=m;j++) for(ll k=j?(j+1):0;k<=m;k++){ id[i][j][k]=++cnt; pi[cnt]=i;pj[cnt]=j;pk[cnt]=k; } ll p[3]; for(ll i=0;i<=m;i++) for(ll j=0;j<=m;j++) for(ll k=0;k<=m;k++){ p[0]=i;p[1]=j;p[2]=k;sort(p,p+3); id[i][j][k]=id[p[0]][p[1]][p[2]]; } return; } signed main() { scanf("%lld%lld",&n,&m); for(ll i=1;i<=n;i++){ scanf("%s",s+1); for(ll j=1;j<=m;j++) if(s[j]=='#')v[i][j]=1; } m++; for(ll i=1;i<=n;i++)v[i][m]=1; ll g=0;f[0][1][0][0]=1;init(); for(ll p=1;p<=n*m;p++){ ll x=(p-1)/m+1,y=(p-1)%m+1; g^=1;memset(f[g],0,sizeof(f[g])); for(ll s=1;s<=cnt;s++){ ll a=pi[s],b=pj[s],c=pk[s]; for(ll k=0;k<=3;k++){ if(f[!g][s][k][0]){ if(!v[x][y]){ f[g][s][k][0]+=f[!g][s][k][0]; if(y==a)f[g][id[0][b][c]][k][1]+=f[!g][s][k][0]; else if(y==b)f[g][id[a][0][c]][k][1]+=f[!g][s][k][0]; else if(y==c)f[g][id[a][b][0]][k][1]+=f[!g][s][k][0]; else if(k<3) f[g][id[y][b][c]][k+1][0]+=f[!g][s][k][0]; } else if(y!=a&&y!=b&&y!=c) f[g][s][k][0]+=f[!g][s][k][0]; } if(f[!g][s][k][1]&&!v[x][y]&&y!=a&&y!=b&&y!=c){ f[g][s][k][1]+=f[!g][s][k][1]; f[g][s][k][0]+=f[!g][s][k][1]; } } } } printf("%lld\n",f[g][1][3][0]); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14456114.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(68)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示