[luoguP1736] 创意吃鱼法(DP)

传送门

f[i][j][0] 表示从右下角到左上角,以(i,j)为起点能延伸的最大值

f[i][j][1] 表示从左下角到右上角,以(i,j)为起点能延伸的最大值

up[i][j] 表示(i,j)上面有多少个0

left[i][j] 表示(i,j)左边有多少个0

right[i][j] 表示(i,j)右边有多少个0

f[i][j][0] = min(f[i - 1][j - 1][0], up[i][j], left[i][j]) + 1

f[i][j][1] = min(f[i - 1][j + 1][1], up[i][j], right[i][j]) + 1

代码

#include <cstdio>
#include <iostream>
#define N 2510
#define max(x, y) ((x) > (y) ? (x) : (y))
#define min(x, y) ((x) < (y) ? (x) : (y))

int n, m, ans;
unsigned short up[N][N], left[N][N], right[N][N], f[N][N][2];
bool a[N][N];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
    for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
    return x * f;
}

int main()
{
	int i, j;
	n = read();
	m = read();
	for(i = 1; i <= n; i++)
		for(j = 1; j <= m; j++)
		{
			f[i][j][0] = f[i][j][1] = a[i][j] = read();
			up[i][j] = a[i - 1][j] ? 0 : up[i - 1][j] + 1;
			left[i][j] = a[i][j - 1] ? 0 : left[i][j - 1] + 1;
		}
	for(i = 1; i <= n; i++)
		for(j = m; j >= 1; j--)
			right[i][j] = a[i][j + 1] ? 0 : right[i][j + 1] + 1;
	for(i = 1; i <= n; i++)
		for(j = 1; j <= m; j++)
		{
			if(!a[i][j]) continue;
			f[i][j][0] = min(f[i - 1][j - 1][0], min(up[i][j], left[i][j])) + 1;
			f[i][j][1] = min(f[i - 1][j + 1][1], min(up[i][j], right[i][j])) + 1;
			ans = max(ans, max(f[i][j][0], f[i][j][1]));
		}
	printf("%d\n", ans);
	return 0;
}

  

时间: 2024-11-04 16:44:45

[luoguP1736] 创意吃鱼法(DP)的相关文章

[P1736]创意吃鱼法[DP]

开始没看到要求对角线以外的地方不能是0,以为是个xx题...照着题解思路写的,很妙啊 题意:给定01矩阵 求矩阵中最长的只有对角线是1的正方形的对角线长度 x[i][j]从(i,j)向左/右(不包括(i,j))的连续的0的数量 y[i][j]从(i,j)向上(不包括(i,j))的连续的0的数量 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int eps = 1e-8; 5 t

P1387 最大正方形+P1736 创意吃鱼法(矩形上的dp+预处理)

最大正方形 1 //找出一个01矩阵中最大的全为一的正方形,并输出边长 2 #include <iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstring> 7 #include<algorithm> 8 #include<cmath> 9 #define LL long long 10 using namesp

P1736 创意吃鱼法

刚开始没想到怎么折状态转移 后来jfdalao给我讲了一遍才会 因为正方形的大小受到端点是否有鱼的限制 所以我们设s1(s2)i,j表示i,j左边(上面)最多有几个0 令f i,j表示以i,j为右下端点并且对角线经过i,j的对角线最大值 显然只有ai,j为1是才能转移 另外因为对角线有两个方向 所以我们应正反求两次 (代码是看别人的) //P1736 创意吃鱼法 #include<bits/stdc++.h> using namespace std; int a[2505][2505],f[2

TYVJ P1736 创意吃鱼法 Label:dp || 前缀和

题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略. 在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵“对角线的一端”下口,只一吸,就能把对角线上的那一队鲜鱼吸入口中. 猫猫是个贪婪的家伙,所以她想一口吃掉尽量多的

洛谷P1736 创意吃鱼法

题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略. 在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵“对角线的一端”下口,只一吸,就能把对角线上的那一队鲜鱼吸入口中. 猫猫是个贪婪的家伙,所以她想一口吃掉尽量多的

洛谷 P1736 创意吃鱼法

题目描述 题目链接:https://www.luogu.org/problemnew/show/P1736 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略. 在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵"对角线的一端

luogu1736 创意吃鱼法

好的题解使人一下就懂啊-- s1[i][j]表示(i,j)最多向左(或右)延伸多少个格子,使这些格子中的数都是0(不包括(i,j)) s2[i][j]表示(i,j)最多向上延伸多少个格子,使这些格子中的数都是0(不包括(i,j)) f[i][j]表以(i,j)为右下(左下)角的最大对角线长度 来自这里 #include <iostream> #include <cstring> #include <cstdio> using namespace std; int n,

【动态规划】创意吃鱼法

原题传送门 思路 呃呃,先咕着,以后再补. Code #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<string> #include<map> typedef long long ll; using namespace std; int n,m,ans; int a[2509][2509],f[2509][2509]

python学习之乌龟吃鱼and思聪吃热狗游戏

乌龟吃鱼游戏游戏规则:1). 假设游戏场景为范围(x,y)为0<=x<=10,0<=y<=102). 游戏生成1只乌龟和10条鱼, 它们的移动方向均随机3). 乌龟的最大移动能力为2(它可以随机选择1还是2移动),鱼儿的最大移动能力是1当移动到场景边缘,自动向反方向移动4). 乌龟初始化体力为100(上限), 乌龟每移动一次,体力消耗1当乌龟和鱼坐标重叠,乌龟吃掉鱼,乌龟体力增加20, 鱼暂不计算体力5). 当乌龟体力值为0(挂掉)或者鱼儿的数量为0游戏结束 01_turtle_f