Vijos1057 盖房子(DP经典题)

之前没有怎么刷过dp的题,所以在此学习了~(感谢walala大神的思路,给了我很大的启发)

也算是自己学习的另一种dp题型吧

先贴上状态转移方程:

if(a[i][j])

f[i][j]=min(f[i-1][j],min(f[i][j-1],f[i-1][j-1]))+1 然后更新ans即可

详细的解释一下这个状态转移方程的意义

F[i-1,j] 表示向左能延伸的最大长度

F[i-1,j-1] 表示沿对角线延伸的最大长度

F[i,j-1] 表示向上能延伸的最大长度

很多人一开始不明白为什么明明是求最大的正方形面积还用min

仔细想想其实很容易想明白

要是当前所求的面积是一个正方形,应该满足向左向上沿对角线延伸的长度相同

怎么使它们延伸的长度相同,并且使这个长度尽量长呢?

求min(f[i-1][j],min(f[i][j-1],f[i-1][j-1]))即可

为什么这里要+1?

这个更好理解了,因为if(a[i][j]) 要加上它自身啊....

想清楚了其实觉得DP也挺有意思的

附上代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int n,m;
int a[1001][1001],f[1001][1001];
int ans;
int main(){
	//freopen("data.txt","r",stdin);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	   for(int j=1;j<=m;j++){
	   	  scanf("%d",&a[i][j]);
	   }
	for(int i=1;i<=n;i++)
	   for(int j=1;j<=m;j++){
	   	   if(a[i][j]) f[i][j]=min(f[i-1][j],min(f[i][j-1],f[i-1][j-1]))+1;
	   	   if(f[i][j]>ans) ans=f[i][j];
	   }
	cout<<ans;
	return 0;
}

  

时间: 2024-10-14 21:33:20

Vijos1057 盖房子(DP经典题)的相关文章

POJ 2411 &amp;&amp; HDU 1400 Mondriaan&#39;s Dream (状压dp 经典题)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12341   Accepted: 7204 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

树形DP经典题

题目传送门 题意: 给出一棵树,求离每个节点最远的点的距离 思路: 把无根树转化成有根树分析, 对于上面那棵树,要求距结点2的最长距离,那么,就需要知道以2为顶点的子树(蓝色圈起的部分,我们叫它Tree(2)),距顶点2的最远距离L1 还有知道2的父节点1为根节点的树Tree(1)-Tree(2)部分(即红色圈起部分),距离结点1的最长距离+dist(1,2) = L2,那么最终距离结点2最远的距离就是max{L1,L2} f[i][0],表示顶点为i的子树的,距顶点i的最长距离 f[i][1]

vijos 1057 盖房子 dp 最大子正方形

P1057盖房子 未递交 标签:[显示标签] 描述 永恒の灵魂最近得到了面积为n*m的一大块土地(高兴ING^_^),他想在这块土地上建造一所房子,这个房子必须是正方形的. 但是,这块土地并非十全十美,上面有很多不平坦的地方(也可以叫瑕疵).这些瑕疵十分恶心,以至于根本不能在上面盖一砖一瓦. 他希望找到一块最大的正方形无瑕疵土地来盖房子. 不过,这并不是什么难题,永恒の灵魂在10分钟内就轻松解决了这个问题. 现在,您也来试试吧. 格式 输入格式 输入文件第一行为两个整数n,m(1<=n,m<=

HDU 2196 Computer 树形DP 经典题

给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权,放在数组cost中 令tree(i)表示以节点i为根的子树 对于节点i,离该节点最远的点要不就是在tree(i)中,要不就是在father(i)上面 令: dp[i][1] : 在子树tree(i)中,离i最远的距离 dp[i][2] : 在子树tree(i)中,离i第二远的距离 (递推的时候需要)

POJ 1155 TELE 背包型树形DP 经典题

由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送数据到达另一个节点,电视台需要一定的费用 若可以传送数据到达用户的节点n-m+1~n,这些用户各自愿意支付一定的费用给电视台 现在电视台希望在不亏本的情况下为尽量多的用户转播比赛 输出最多可以为多少用户转播比赛 背包类型的树形DP第一题 dp[i][j]表示以节点i为根的子树有j个用户获得转播,电视

二维状压DP经典题

炮兵阵地 题目链接 题目大意:在n*m的地图上放置炮兵,每个炮兵的攻击范围是上下左右两格内,有两种不同的地形,山地(用"H" 表示),平原(用"P"表示),只有平原可以布置炮兵,在不冲突的前提下最多可以布置多少炮兵? 这道题非常经典,我们用dp[i] [j] [k]表示第i行在第j种选取状态下,第i-1行在第k种选取状态下前i行最多摆放的炮兵数量.然后我们首先预处理每一行所有的合法状态,以降低时间复杂度.用num[i]表示第i行的合法状态数量,state[i] [j

HDU 2196 Computer 树形DP经典题

链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问每台电脑和其它电脑的最远距离是多少. 思路:这是一道树形DP的经典题目.须要两次DFS,第一次DFS找到树上全部的节点在不同子树中的最远距离和次远的距离(在递归中进行动态规划就可以),第二次DFS从根向下更新出终于答案.对于每次更新到的节点u,他的最远距离可能是来自u的子树,或者是u的父亲节点的最远

hdu1158 dp经典题

题意:已知雇佣员工花费(h).解雇员工花费(f).员工每月薪水(s),员工未被解雇的话即使未工作也要付薪水,现知道每个月需要几名员工,求最低花费. 很显然,刷 DP 专题的我早早地就意识到这是一道 DP 题(呵呵,废话你在刷DP```),我最开始的思路是这样的,开一个一维数组 dp [ i ]  来记录第 i 个月的最低花费情况,同时另开一个平行数组记录该情况下的人数,通过第 i 月的需求人数与上个月的最优情况的人数比较,进行 DP .但是很快我就发现,情况的种类很多很复杂,并且在第 i 个月的

HDU - 1003 Max Sum(DP经典题2)

题意:给出一串数,求最大和的字串和起始终点位置. 与导弹问题大同小异,有状态转移方程就很好做了. 状态转移方程:d[i]=(d[i-1]+a[i]>a[i])?d[i-1]+a[i]:a[i]; 1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 const int maxn=100000+10; 6 7 int dp[maxn],num[maxn]; 8 9 int main(){ 10