首页 > 其他分享 >【题解】Luogu P7171 [COCI2020-2021#3] Selotejp

【题解】Luogu P7171 [COCI2020-2021#3] Selotejp

时间:2025-01-02 14:10:06浏览次数:5  
标签:COCI2020 rsh P7171 覆盖 题解 nx ny operatorname

注:题解中 \(\operatorname{lsh}\),\(\operatorname{rsh}\),\(\operatorname{or}\) 分别表示按位左移、按位右移、按位或,即 c++ 语言中的 <<>>|

我也是打上轮廓线 DP 了。

设 \(f_{x,y,S}\) 表示当前在 \((x,y)\) 格子,前 \(m\) 个格子的状态为 \(S\) 时的最小花费。

这里的状态是指,这一格竖着覆盖为 \(1\),横着覆盖或本来就不用覆盖为 \(0\)。

这里的前 \(m\) 个格子如下图所示,假设 \(m=4\),当前在 \((2,2)\),方格内的数表示在 \(S\) 中从低到高的下标(从 \(0\) 开始):

它就是一个逐行遍历矩阵的顺序,注意是包括 \((x,y)\) 这一格的。

为什么要这样记录呢,因为存在竖着覆盖,如刚才的例子,\((2,2)\) 的下一个为 \((2,3)\),它的上面是 \((1,3)\),刚好被记录了状态。

于是转移其实不难想:

  • 下一位 \((nx,ny)\) 为 #
    • 横着覆盖,判断左边有没有点,且这个点是不是横着覆盖的,即 \(f_{nx,ny,S\operatorname{rsh}1}\) 从 \(f_{x,y,S}\) 或 \(f_{x,y,S}+1\) 转移。
    • 竖着覆盖,判断上面的点是不是竖着覆盖的,即 \(f_{nx,ny,(S\operatorname{rsh}1)\operatorname{or}(1\operatorname{lsh}(m-1))}\) 从 \(f_{x,y,S}\) 或 \(f_{x,y,S}+1\) 转移。
  • 下一位为 .,直接让 \(f_{nx,ny,S\operatorname{rsh}1}\) 从 \(f_{x,y,S}\) 转移。

复杂度 \(O(nm2^m)\)。

#include<bits/stdc++.h>
#define ll long long
#define il inline
#define read(x){\
	char ch;\
	int fu=1;\
	while(!isdigit(ch=getchar()))\
		fu-=(ch=='-')<<1;\
	x=ch&15;\
	while(isdigit(ch=getchar()))\
		x=(x<<1)+(x<<3)+(ch&15);\
	x*=fu;\
}

using namespace std;
namespace asbt{
namespace cplx{bool begin;}
const int maxn=(1<<10)+5;
const int inf=0x3f3f3f3f;
int n,m,f[maxn][15][maxn];
char s[maxn][15];
il void upd(int &x,int y){
	x=min(x,y);
}
namespace cplx{
	bool end;
	il double usdmem(){return (&begin-&end)/1048576.0;}
}
int main(){
	read(n)read(m);
	for(int i=1;i<=n;i++){
		scanf(" %s",s[i]+1);
	}
	memset(f,0x3f,sizeof f);
	if(s[1][1]=='#'){
		f[1][1][0]=f[1][1][1<<(m-1)]=1;
	}
	else{
		f[1][1][0]=0;
	}
	for(int x=1;x<=n;x++){
		for(int y=1;y<=m;y++){
			for(int S=0,nx,ny;S<1<<m;S++){
				if(f[x][y][S]>=inf){
					continue;
				}
				nx=x+y/m;
				ny=y%m+1;
				if(s[nx][ny]=='#'){
					if(ny>1&&(S>>(m-1)&1)==0&&s[x][y]=='#'){
						upd(f[nx][ny][S>>1],f[x][y][S]);
					}
					else{
						upd(f[nx][ny][S>>1],f[x][y][S]+1);
					}
					if(nx>1&&(S&1)){
						upd(f[nx][ny][S>>1|1<<(m-1)],f[x][y][S]);
					}
					else{
						upd(f[nx][ny][S>>1|1<<(m-1)],f[x][y][S]+1);
					}
				}
				else{
					upd(f[nx][ny][S>>1],f[x][y][S]);
				}
			}
		}
	}
	int ans=inf;
	for(int S=0;S<1<<m;S++){
		ans=min(ans,f[n][m][S]);
	}
	printf("%d",ans);
	return 0;
}
}
int main(){return asbt::main();}

标签:COCI2020,rsh,P7171,覆盖,题解,nx,ny,operatorname
From: https://www.cnblogs.com/zhangxyhp/p/18647538

相关文章

  • USACO2024DEC题解
    P11450[USACO24DEC]FarmerJohn'sCheeseBlockB//FarmerJohn'sCheeseBlockB#include<stdio.h>#include<iostream>usingnamespacestd;intcnt_xy[1005][1005],cnt_yz[1005][1005],cnt_xz[1005][1005];intmain(){intn,q;......
  • [CF2353D] Refined Product Optimality 题解
    首先让我们输出的是不操作的值。不定序,一看就很贪心。经过分类分类分类可证,\(a,b\)都是升序(降序)的时候是最优的。再看加操作的。相当于要维护这两个升序序列。我们发现,每次操作影响的值很少,最多两个值。在一个连续段中,修改的值相当于和末尾值交换,再加一。唐点:找这个末尾没必要......
  • CF848E Days of Floral Colours 题解
    Problem-848E-Codeforces首先,由于整个图是对称的,所以我们将其沿直径分为两半,在算一半答案时把每一段的贡献平方再相加即可。(因为对面也有一段相同长度的也要计入贡献)现在我们的问题转化为了对于一个长为\(n\)的环,你可以给一个点连出一个线头(即在原图中连向对面的边)将其余......
  • Luogu P9646 SNCPC2019 Paper-cutting 题解 [ 紫 ] [ manacher ] [ 贪心 ] [ 哈希 ] [
    Paper-cutting:思维很好,但代码很构式的manacher题。蒟蒻2025年切的第一道题,是个紫,并且基本独立想出的,特此纪念。判断能否折叠我们先考虑一部分能折叠需要满足什么条件。显然,这一部分需要是一个长度为偶数的回文串。那么横向和纵向会不会影响呢?答案是不会,因为横向折了之后,折......
  • CF601E A Museum Robbery 题解
    题目传送门前置知识线段树与离线询问解法普通的回退背包无法处理本题中的删除操作,考虑线段树分治后转化为只进行添加的背包。具体实现时可以对每个深度开一个背包的转移数组,时间复杂度为\(O(nk\logq+qk)\),可以接受。代码#include<bits/stdc++.h>usingnamespacestd;#......
  • 洛谷 P11487 「Cfz Round 5」Gnirts 10——题解
    洛谷P11487「CfzRound5」Gnirts10传送锚点摸鱼环节「CfzRound5」Gnirts10题目背景Englishstatement.YoumustsubmityourcodeattheChineseversionofthestatement.InMemoryof\(\text{F}\rule{66.8px}{6.8px}\).题目描述题面还是简单一点好。给定......
  • 题解:AT_abc386_d [ABC386D] Diagonal Separation
    分析题面,发现题目求的是是否存在一个白点被\((1,1)\)和任意一个黑点围成的矩形内。先将所有黑点按\(x\)坐标排序。枚举所有的白点。找到所有横坐标不比该白点横坐标小的所有黑点的纵坐标的最大值所属点。如果该点的纵坐标小于该白点的纵坐标:(蓝点代表题目中的白点,红点......
  • 百丽宫24年春季真题题解——回型字符的打印
    不妨参考之前的一道选做题思路(虽然楼主自己之前也没找到时间做)但当时瞟过一眼题目,个人认为可以一起做,都是你中有我的关系,思路很相似。选做题摘录——晕:看着这样的"回”形图案你晕吗?让我们不用数组,来做出它。输入格式:n。正方形的边长输出格式:"%3d"   边长为n的数字回......
  • 百丽宫22年真题题解——最短路径(排列组合法)
    #include<stdio.h>unsignedlonglonghigh;unsignedlonglonglow;unsignedlonglongfac(intn,intm){unsignedlonglongi,f=1;if(m!=1){for(i=n;i>=n-m+1;i--){f=f*i;}returnf;}elseif(m......
  • 自动推理与规划:让机器具备智能决策与问题解决能力
    随着人工智能技术的不断进步,自动推理与规划(AutomatedReasoningandPlanning)已经成为使机器具备高效决策和问题解决能力的核心技术之一。它涉及如何通过逻辑推理、任务规划和约束求解,使机器能够自主地解决复杂问题、制定行动策略,并在不断变化的环境中做出最优决策。自动推理......