BZOJ 3128 Usaco2013 Open Figure Eight

题目大意:给定一个有坏点的矩阵,求能画出来的最大的“8”字形

“8”字形满足:

*数字8由上下两个矩形构成。
*数字8的上下两个矩形都满足至少有一个单元格在矩形内部。
*数字8顶部的矩形的底边必须为底部矩形顶边的子集。
*数字8只能刻在大理石完美无瑕的部分。
*规定数字8的得分为上矩形和下矩形的面积的乘积,它们希望得分能达到最大。

枚举顶部矩形的底边,可以用上一行的底边O(1)转移得到,然后每行O(n^2)向左右拓展

然后枚举底部矩形的顶边,可以用下一行的顶边O(1)转移得到,顶部矩形的最大面积已求出,O(1)更新答案

最终时间复杂度O(n^3) 小心内存

尼玛考试时无解判挂丢了10分。。。简直。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 302
using namespace std;
int n;
long long ans=-1;
char map[M][M];
int sum[M][M];
int f[M][M][M],g[M][M][M];
int Get_Sum(int x1,int y1,int x2,int y2)
{
	return sum[x2][y2]+sum[x1-1][y1-1]-sum[x2][y1-1]-sum[x1-1][y2];
}
int main()
{
	freopen("eight.in","r",stdin);
	freopen("eight.out","w",stdout);
	int i,j,k;
	cin>>n;
	for(i=1;i<=n;i++)
		scanf("%s",map[i]+1);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+(map[i][j]=='*');
	for(i=1;i<=n-2;i++)
		for(j=i+2;j<=n;j++)
		{
			int last=0;
			for(k=1;k<=n;k++)
			{
				if(map[k][i]=='*'||map[k][j]=='*')
					last=0;
				if(!Get_Sum(k,i,k,j))
				{
					if(last)
						f[k][i][j]=(k-last-1)*(j-i-1);
					else
						last=k;
				}
			}
			last=0;
			for(k=n;k;k--)
			{
				if(map[k][i]=='*'||map[k][j]=='*')
					last=0;
				if(!Get_Sum(k,i,k,j))
				{
					if(last)
						g[k][i][j]=(last-k-1)*(j-i-1);
					else
						last=k;
				}
			}
		}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n-3;j++)
			for(k=j+3;k<=n;k++)
			{
				if(Get_Sum(i,j,i,k))
					break;
				f[i][j][k]=max(f[i][j][k],f[i][j][k-1]);
			}
		for(j=n;j>=4;j--)
			for(k=j-3;k;k--)
			{
				if(Get_Sum(i,k,i,j))
					break;
				f[i][k][j]=max(f[i][k][j],f[i][k+1][j]);
			}
	}
	for(i=3;i<=n-2;i++)
		for(j=1;j<=n-2;j++)
			for(k=j+2;k<=n;k++)
				if(!Get_Sum(i,j,i,k))
					ans=max(ans,(long long)f[i][j][k]*g[i][j][k]);
	cout<<ans<<endl;
}
//あぁ 花火が夜空 綺麗に咲いて ちょっと切なく
//	あぁ 風が時間と ともに流れる


Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
题目描述 牛牛和她的朋友们正在玩一个有趣的游戏,他们需要构建一个有 $n$ 个节点的无向图,每个节点都有一个唯一的编号并且编号从 $1$ 到 $n$。他们需要从节点 $1$ 到节点 $n$ 找到一条最短路径,其中路径长度是经过的边权的和。为了让游戏更有趣,他们决定在图上添加一些额外的边,这些边的权值都是 $x$。他们想知道,如果他们添加的边数尽可能少,最短路径的长度最多会增加多少。 输入格式 第一行包含两个正整数 $n$ 和 $m$,表示节点数和边数。 接下来 $m$ 行,每行包含三个整数 $u_i,v_i,w_i$,表示一条无向边 $(u_i,v_i)$,权值为 $w_i$。 输出格式 输出一个整数,表示最短路径的长度最多会增加多少。 数据范围 $2 \leq n \leq 200$ $1 \leq m \leq n(n-1)/2$ $1 \leq w_i \leq 10^6$ 输入样例 #1: 4 4 1 2 2 2 3 3 3 4 4 4 1 5 输出样例 #1: 5 输入样例 #2: 4 3 1 2 1 2 3 2 3 4 3 输出样例 #2: 2 算法 (BFS+最短路) $O(n^3)$ 我们把问题转化一下,假设原图中没有添加边,所求的就是点 $1$ 到点 $n$ 的最短路,并且我们已经求出了这个最短路的长度 $dis$。 接下来我们从小到大枚举边权 $x$,每次将 $x$ 加入图中,然后再次求解点 $1$ 到点 $n$ 的最短路 $dis'$,那么增加的最短路长度就是 $dis'-dis$。 我们发现,每次加入一个边都需要重新求解最短路。如果我们使用 Dijkstra 算法的话,每次加入一条边需要 $O(m\log m)$ 的时间复杂度,总的时间复杂度就是 $O(m^2\log m)$,无法通过本题。因此我们需要使用更优秀的算法。 观察到 $n$ 的范围比较小,我们可以考虑使用 BFS 求解最短路。如果边权均为 $1$,那么 BFS 可以在 $O(m)$ 的时间复杂度内求解最短路。那么如果我们只是加入了一条边的话,我们可以将边权为 $x$ 的边看做 $x$ 条边的组合,每次加入该边时,我们就在原始图上添加 $x$ 条边,边权均为 $1$。这样,我们就可以使用一次 BFS 求解最短路了。 但是,我们不得不考虑加入多条边的情况。如果我们还是将边权为 $x$ 的边看做 $x$ 条边的组合,那么我们就需要加入 $x$ 条边,而不是一条边。这样,我们就不能使用 BFS 了。 但是,我们可以使用 Floyd 算法。事实上,我们每次加入边时,只有边权等于 $x$ 的边会发生变化。因此,如果我们枚举边权 $x$ 时,每次只需要将边权等于 $x$ 的边加入图中,然后使用 Floyd 算法重新计算最短路即可。由于 Floyd 算法的时间复杂度为 $O(n^3)$,因此总的时间复杂度为 $O(n^4)$。 时间复杂度 $O(n^4)$ 空间复杂度 $O(n^2)$ C++ 代码 注意点:Floyd算法计算任意两点之间的最短路径,只需要在之前的路径基础上加入新的边构成的新路径进行更新即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值