最大矩阵(简单DP)
见题:

很水的一题,数据范围太小,前缀和加爆搜就行.
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int ans=,m,n,sum[maxn][maxn];
inline int read()
{
int x=,ff=;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return x*ff;
}
inline void put(int x)
{
if(x<) putchar('-'),x=-x;
if(x>) put(x/);
putchar(x%+'');
}
int main()
{
//freopen("1.in","r",stdin);
n=read();m=read();
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
int x=read();
sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-]+x;
}
}
for(int len=;len<=min(n,m);len++)
{
int he=len*len;
for(int x1=;x1<=n-len+;x1++)
{
for(int y1=;y1<=m-len+;y1++)
{
int x2=x1+len-;
int y2=y1+len-;
if((sum[x2][y2]-sum[x1-][y2]-sum[x2][y1-]+sum[x1-][y1-])==he) ans=len;
}
}
}
put(ans);
return ;
}
可是还是想写正解,DP;
对于这类的二维DP,个人理解就是如果保存的从起点到终点的状态会被一些情况所中断,就要只考虑最下角的点所保存的点的状态,例如此题,我们可以保存以(i,j)为右下角的状态,以f[i][j]保存以(i,j)为最右下角的最大正方形边长.状态转移怎么样呢?
这是我们我们可以轻易的想起二维的前缀和:f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j],那这个能否用前缀和处理呢,见下图:

最右下的小矩阵代表(i,j)可以很清楚地看出由左边的点,上边的点,左上角的点三个点的最小矩阵构成以个完整的矩阵,即:if(a[i][j]==1) f[i][j]=min(f[i-1][j-1],min(f[i-1][j],f[i][j-1]))+1;
这也提醒我们min的意义就是几个状态都具备的共同元素.
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int m,n,a[maxn][maxn],f[maxn][maxn],ans;
inline int read()
{
int x=,ff=;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return x*ff;
}
int put(int x)
{
if(x<) putchar('-'),x=-x;
if(x>) put(x/);
putchar(x%+'');
}
inline void DP()
{
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(a[i][j]==) f[i][j]=min(f[i-][j-],min(f[i-][j],f[i][j-]))+;
ans=max(ans,f[i][j]);
}
}
}
int main()
{
freopen("1.in","r",stdin);
n=read();m=read();
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++) a[i][j]=read();
}
DP();
put(ans);
return ;
}
下一题:


这一题就不能用暴力了,(n<=2600,m<=2600)只能想正解,和上一题一样我们可以用f[i][j]一(i,j)保存合法的吃到的最大的鱼的个数.
接下来就考虑状态怎么转移,我自己也是嗑了许多时间还没做出来,于是就看了题解...

给出代码:
#include<bits/stdc++.h>
using namespace std;
#define _ 0
const int maxn=;
int m,n,a[maxn][maxn],f[maxn][maxn],s1[maxn][maxn],s2[maxn][maxn],ans;
inline int read()
{
int x=,ff=;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return x*ff;
}
inline void put(int x)
{
if(x<) putchar('-'),x=-x;
if(x>) put(x/);
putchar(x%+'');
}
int main()
{
freopen("1.in","r",stdin);
n=read();m=read();
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++) a[i][j]=read();
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(!a[i][j])
{
s1[i][j]=s1[i][j-]+;
s2[i][j]=s2[i-][j]+;
}
if(a[i][j])
{
f[i][j]=min(f[i-][j-],min(s1[i][j-],s2[i-][j]))+;
ans=max(ans,f[i][j]);
}
}
}
memset(f,,sizeof(f));
memset(s1,,sizeof(s1));
memset(s2,,sizeof(s2));
for(int i=;i<=n;i++)
{
for(int j=m;j>=;j--)
{
if(!a[i][j])
{
s1[i][j]=s1[i][j+]+;
s2[i][j]=s2[i-][j]+;
}
if(a[i][j])
{
f[i][j]=min(f[i-][j+],min(s1[i][j+],s2[i-][j]))+;
ans=max(ans,f[i][j]);
}
}
}
put(ans);
return (^_^);
}
启示我们可以直接从最优解的转移推状态转移方程...
最大矩阵(简单DP)的更多相关文章
- Codeforces 41D Pawn 简单dp
题目链接:点击打开链接 给定n*m 的矩阵 常数k 以下一个n*m的矩阵,每一个位置由 0-9的一个整数表示 问: 从最后一行開始向上走到第一行使得路径上的和 % (k+1) == 0 每一个格子仅仅 ...
- 矩阵优化dp
链接:https://www.luogu.org/problemnew/show/P1939 题解: 矩阵优化dp模板题 搞清楚矩阵是怎么乘的构造一下矩阵就很简单了 代码: #include < ...
- [六省联考2017]组合数问题 (矩阵优化$dp$)
题目链接 Solution 矩阵优化 \(dp\). 题中给出的式子的意思就是: 求 nk 个物品中选出 mod k 为 r 的个数的物品的方案数. 考虑朴素 \(dp\) ,定义状态 \(f[i][ ...
- [BZOJ 4818/LuoguP3702][SDOI2017] 序列计数 (矩阵加速DP)
题面: 传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4818 Solution 看到这道题,我们不妨先考虑一下20分怎么搞 想到暴力,本蒟 ...
- hdu2067 简单dp或者记忆化搜索
题意: 小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 1087 简单dp,求递增子序列使和最大
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- C#的winform矩阵简单运算
C#的winform矩阵简单运算 程序截图 关键代码 using System; using System.Collections.Generic; using System.ComponentMod ...
- Codeforces Round #260 (Div. 1) A. Boredom (简单dp)
题目链接:http://codeforces.com/problemset/problem/455/A 给你n个数,要是其中取一个大小为x的数,那x+1和x-1都不能取了,问你最后取完最大的和是多少. ...
- codeforces Gym 100500H A. Potion of Immortality 简单DP
Problem H. ICPC QuestTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100500/a ...
- 简单dp --- HDU1248寒冰王座
题目链接 这道题也是简单dp里面的一种经典类型,递推式就是dp[i] = min(dp[i-150], dp[i-200], dp[i-350]) 代码如下: #include<iostream ...
随机推荐
- Dubbo和Spring Cloud
1.Dubbo和Spring Cloud区别 1).通信方式不同 Dubbo使用RPC通信,Spring Cloud使用Http RestFul方式 2) 组成部分不同 组件 Dubbo Spring ...
- [ZZ] 用matlab绘制箭头
用matlab绘制箭头 http://npfeng900.blog.163.com/blog/static/14456108201221922944998/ 用matlab绘制箭头1 用matlab绘 ...
- 【配置阿里云 I】申请配置阿里云服务器,并部署IIS和开发环境,项目上线经验
https://blog.csdn.net/vapaad1/article/details/78769520 最近一年在实验室做web后端开发,涉及到一些和服务器搭建及部署上线项目的相关经验,写个帖子 ...
- Spring3基础原理解析
一.Spring3主要含义 Spring3是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. 注:IOC的作用:对象依赖的其他对象通过被动的形式传递进来而不是这个对象常见或者查找依赖对象 ...
- 使用SimpleDateFormat类来实现时间跟字符串的转化
使用Date和SimpleDateFormat类表示时间 1.Date类 需要处理日期和时间的相关数据时可以使用 java.util 包中的 Date 类,这个类最主要的作用就是获取当前时间.下面看看 ...
- Windows 2012 安装 SQL Server 2012,.Net Framework 3.5安装不成的解决办法
This behavior can also be caused by a system administrator who configures the computer to use Window ...
- kmeans
K均值(K-means)算法 ).setSeed(1L) val model=kmeans.fit(dataset) //Make predictions val predictions=model. ...
- vs关于“当前不会命中断点 还没有为该文档加载任何符号”的解决方法
首先调式的时候确定在debug模式下, 解决方法:工具-选项-调试 -(启用“仅我的代码”)勾去掉.
- 正确的学python方式
首先呢,和其他的各种学习都一样,你一定要明白你学习的目标是什么.有的人想要通过学习Python,转行成程序员,实现行业上的转变:有的人希望通过学习Python,在现有的岗位上提升自己:当然也有很多人只 ...
- JavaScript数组方法--filter、find、findIndex
继续数组方法,今天应该到filter了. filter:filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素. 使用: var words = ['spray', 'lim ...