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 namespace std;
11 int mp[109][109];
12 int f[109][109];
13 int m,n;
14
15 int main()
16 {
17     cin>>n>>m;
18     for(int i=1;i<=n;i++)
19     {
20         for(int j=1;j<=m;j++)
21         {
22             cin>>mp[i][j];
23         }
24     }
25     int res=0;
26     for(int i=1;i<=n;i++)
27     {
28         for(int j=1;j<=m;j++)
29         {
30             if(mp[i][j])
31                 f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;//若为一,则从三个方向中选个最小的(不然可能不符合题意)
32             else
33                 f[i][j]=mp[i][j];//是0就填0
34             res=max(f[i][j],res);
35         }
36     }
37     cout<<res;
38     return 0;
39 }

创意吃鱼法

 1 //类似于P1387最大正方形
 2 //磁体是让你找出一个01矩阵中最大的单位方阵,输出边长
 3 #include<iostream>
 4 #include<cstring>
 5 using namespace std;
 6 const int N=3000;
 7 bool mp[N][N];
 8 int s1[N][N],s2[N][N];//s1表示横向有多少个0,s2表示纵向有多少个0
 9 int f[N][N];//方阵边长
10 int main(void)
11 {
12     std::ios::sync_with_stdio(false);
13     int n,m;
14     cin>>n>>m;
15     for(int i=1;i<=n;i++)
16     {
17         for(int j=1;j<=m;j++)
18         {
19             cin>>mp[i][j];
20         }
21     }
22     //左上到右下
23     memset(s1,0,sizeof(s1));
24     memset(s2,0,sizeof(s2));
25     memset(f,0,sizeof(f));
26     int ans=0;
27     for(int i=1;i<=n;i++)
28     {
29         for(int j=1;j<=m;j++)
30         {
31             if(mp[i][j]==0)
32             {
33                 s1[i][j]=s1[i][j-1]+1;
34                 s2[i][j]=s2[i-1][j]+1;
35             }
36             else
37             {
38                 f[i][j]=min(f[i-1][j-1],min(s1[i][j-1],s2[i-1][j]))+1;
39                 ans=max(ans,f[i][j]);
40             }
41         }
42     }
43     //右上到左下
44     memset(s1,0,sizeof(s1));
45     memset(s2,0,sizeof(s2));
46     memset(f,0,sizeof(f));
47     for(int i=1;i<=n;i++)
48     {
49         for(int j=m;j>=1;j--)
50         {
51             if(mp[i][j]==0)
52             {
53                 s1[i][j]=s1[i][j+1]+1;//此处当注意,右上到左下横向应该是加一
54                 s2[i][j]=s2[i-1][j]+1;
55             }
56             else
57             {
58                 f[i][j]=min(f[i-1][j+1],min(s1[i][j+1],s2[i-1][j]))+1;
59                 ans=max(ans,f[i][j]);
60             }
61         }
62     }
63     cout<<ans<<endl;
64     return 0;
65 }

原文地址:https://www.cnblogs.com/greenofyu/p/12236157.html

时间: 2024-11-04 18:19:34

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

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

洛谷 P1736 创意吃鱼法

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

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

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

洛谷P1736 创意吃鱼法

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

[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

[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

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