题目描述

回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*)。她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略。

在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵“对角线的一端”下口,只一吸,就能把对角线上的那一队鲜鱼吸入口中。

猫猫是个贪婪的家伙,所以她想一口吃掉尽量多的鱼。请你帮猫猫计算一下,她一口下去,最多可以吃掉多少条鱼?

输入输出格式

输入格式:

有多组输入数据,每组数据:

第一行有两个整数n和m(n,m≥1),描述池塘规模。接下来的n行,每行有m个数字(非“0”即“1”)。每两个数字之间用空格隔开。

对于30%的数据,有n,m≤100

对于60%的数据,有n,m≤1000

对于100%的数据,有n,m≤2500

输出格式:

只有一个整数——猫猫一口下去可以吃掉的鱼的数量,占一行,行末有回车。

输入输出样例

输入样例#1:

4 6
0 1 0 1 0 0
0 0 1 0 1 0
1 1 0 0 0 1
0 1 1 0 1 0
输出样例#1:

3

说明

右上角的

1 0 0 0 1 0 0 0 1

解法一

这道题虽然是动态规划,但也有非动态规划的做法,看到题解里没有这种做法,就给大家发一下(虽然慢了一点,但比较容易理解):用前缀和、差分,首先对矩阵求前缀和,之后从(0,0)向(n,m)扫描,每扫描到一个点,就向这个点的左上方(i-k,j-k,1<=k<=n)

扫描,如果扫描到0或从(i-k,j-k)到(i,j)这个矩阵的差分(即其中鱼的个数)大于k+1(矩阵对角线长度)则终止扫描,此时k就是从点(i,j)向左上方能吃到的鱼的数量,扫描完之后将整个矩阵左右翻转再进行一次扫描,两次扫描扫到的最大值就是结果。

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define min3(a,b,c) min(a,min(b,c))
using namespace std;
int ans,a[][],b[][],sum[][],N,M,x,y;
void zheng(){
memset(sum,,sizeof(sum));
for(int i=;i<=N;i++){
for(int j=;j<=M;j++)
sum[i][j]=sum[i][j-]+a[i][j];
for(int j=;j<=M;j++)
sum[i][j]+=sum[i-][j];
} for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
if(a[i][j]==){
int k=;
while((k<min(i,j))&&(a[i-k][j-k]==)
&&(sum[i][j]-sum[i-k-][j]-sum[i][j-k-]+sum[i-k-][j-k-])==(k+)){
// printf("i=%d j=%d k=%d\n",i,j,k);
k++;
} ans=max(ans,k);
} }
void change(){
for(int i=;i<=N;i++)
for(int j=;j<=(M+)/;j++)
swap(a[i][j],a[i][M-j+]);
return;
}
int main(){
// freopen("01.txt","r",stdin);
scanf("%d%d",&N,&M);
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
scanf("%d",&a[i][j]); zheng();
change();
/* for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++)
printf("%-3d",sum[i][j]);
puts("");
}*/ zheng(); printf("%d\n",ans);
return ;
}

解法二

动态规划1,f[i][j]表示以(i,j)为顶点的最大子矩阵中能吃到的鱼的条数。

f[i][j]可以从f[i-1][j-1]或f[i-1][j+1]转移而来,取其中最大值。

每次转移需要横向和纵向检查0的个数,取两者最小值k即得到了最大子矩阵中鱼的个数。

C代码:

 #include<stdio.h>
int n,m,i,j,k,k1,k2,max,temp,f[][];
int main(void)
{
while(scanf("%d%d",&n,&m)==)
{
max=;//答案
for(i=;i<=n;i++)
{
for(j=;j<=m;j++)scanf("%d",&f[i][j]);//先输入一行,因为下面要横向检查0的个数。
for(j=;j<=m;j++)
{
if(f[i][j]==)
{
temp=f[i-][j-];//检查左上方
if(temp>= && temp+>f[i][j])
{
for(k1=;k1<=temp;k1++)//横向往左检查0的个数k1,最多为temp个
if(f[i][j-k1]>=) break;
for(k2=;k2<=temp;k2++)//纵向往上检查k2……
if(f[i-k2][j]>=) break;
f[i][j]=k1<k2?k1:k2; //取k1、k2较小的那个,就是满足条件的最大子矩阵。
}
temp=f[i-][j+];//检查右上方
if(temp>= && temp+>f[i][j])
{
for(k1=;k1<=temp;k1++)
if(f[i][j+k1]>=) break;//唯一不同是这里的j+k1而不是j-k1,因为是往右检查
for(k2=;k2<=temp;k2++)
if(f[i-k2][j]>=) break;
f[i][j]=k1<k2?k1:k2;
}
}
if(f[i][j]>max) max=f[i][j];
}
}
printf("%d\n",max);
}
return ;
}

动态规划2:

暴力dp。

首先分类,fl[i,j]表示由左上开始的对角线到(i,j)为终点的最大长度,fr[i,j]为从右上开始的对角线到(i,j)为终点的最大长度。

可以观察到fl[i,j]可以从f[i-1,j-1]转移而来,fr[i,j]可由fr[i-1,j+1]转移而来,当转移完毕后,搜索以当前对角线长为边长正方形上该点的临边有没有鱼,如果有鱼,那么鱼到该点的距离为以该点为终点的对角线长。

 #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[][],fl[][],fr[][];
int main(){
int n,m;
cin>>n>>m;
for(int i = ;i<=n;i++)
for(int j = ;j<=m;j++)scanf("%d",&a[i][j]);
memset(fl,,sizeof(fl));
memset(fr,,sizeof(fr));
for(int i = ;i<=n;i++)//搜索fl
for(int j = ;j<=m;j++)
if(a[i][j]){
fl[i][j] = fl[i-][j-]+;
for(int k = ;k<fl[i][j];k++)if(a[i-k][j]||a[i][j-k]){//验证当前解是否可行
fl[i][j] = k;
break;
}
}
for(int i = ;i<=n;i++)//搜索fr
for(int j = m;j;j--)
if(a[i][j]){
fr[i][j] = fr[i-][j+]+;
for(int k = ;k<fr[i][j];k++)if(a[i-k][j]||a[i][j+k]){//验证当前解是否可行
fr[i][j] = k;
break;
}
}
int ans = ;
for(int i = ;i<=n;i++)
for(int j = ;j<=m;j++)ans = max(ans,max(fl[i][j],fr[i][j]));
cout<<ans<<endl;
return ;
}

同类题目http://www.cnblogs.com/radiumlrb/p/5808285.html

洛谷 P1736 创意吃鱼法 Label:dp || 前缀和的更多相关文章

  1. 洛谷 P1736 创意吃鱼法

    题目描述 题目链接:https://www.luogu.org/problemnew/show/P1736 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢( ...

  2. 洛谷P1736 创意吃鱼法

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

  3. 洛谷P1736 创意吃鱼法 dp

    正解:dp 解题报告: 早就想写dp的题目辣!我发现我的dp好差啊QAQ所以看到列表的小朋友写dp的题目就跟着他们的步伐做下题好辣QwQ 这题的话没有那——么难,大概说下趴QwQ 首先说下题意 前面一 ...

  4. 洛谷 P1736 创意吃鱼法(多维DP)

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

  5. P1387 最大正方形 && P1736 创意吃鱼法(DP)

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  6. Luogu P1736 创意吃鱼法【dp】By cellur925

    题目传送门 题意:给出一个01矩阵,找出一条对角线,使得对角线上的元素都为1,而对角线所在矩阵其他元素均为0,使得这样的对角线最长. 状态:$f[i][j]$表示以($i$,$j$)为对角线端点的最长 ...

  7. P1387 最大正方形&&P1736 创意吃鱼法

    P1387 最大正方形 P1736 创意吃鱼法 两道类似的$DP$ 转移方程基本上类似于$f[i][j]=min(f[i-1][j-1],min(f[i][j-1],f[i-1][j]))$ 考虑构成 ...

  8. P1736 创意吃鱼法 图的DP

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

  9. P1736 创意吃鱼法

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

随机推荐

  1. python基础知识

    由于python的灵活性,赋值前无需强调变量的数据类型,并且变量的数据类型在后期的操作过程中还可以改变,故不介绍关键字,直接定义方法及可以调用的方法. I  基本数据类型 一.字符串 1.使用单引号或 ...

  2. uboot学习第一天

    Windows操作系统BIOS(设置) Windows系统 文件系统 驱动程序 应用程序 linux操作系统bootloader(引导系统) kernel(内核) 文件系统 驱动程序 应用程序 交叉编 ...

  3. XHTML的规则

    以正确的DOCTYPE和命名空间开始文档 使用meta内容元素声明你的字符编码 用小写字母写所有元素和属性名称 给所有属性值加引号 给所有属性赋一个值 关闭所有标签 用空格和斜杠关闭“空”标签 不要在 ...

  4. 常用的Mysql数据库操作语句大全

    一.用户管理: 1.新建用户: >CREATE USER name IDENTIFIED BY 'ssapdrow'; 2.更改密码: >SET PASSWORD FOR name=PAS ...

  5. mapReduce编程之auto complete

    1 n-gram模型与auto complete n-gram模型是假设文本中一个词出现的概率只与它前面的N-1个词相关.auto complete的原理就是,根据用户输入的词,将后续出现概率较大的词 ...

  6. mysql 最大连接数 & 连接池

    MySQL最大连接数 关于最大连接数:http://mg123.lofter.com/post/1a5f3e_996f838 可以通过修改配置文件(默认/etc/my.cnf)中的"mysq ...

  7. ViewState与Session [转]

    昨天偶然看到网上有人讨论究竟是该用viewstate还是session来保存信息. 忽然觉得有必要去深入的研究一下这两个东东了,我们先来看深入分析一下viewstate, 为了分析的相对完整性,先从简 ...

  8. vmware12 ubuntu14.01桥接模式静态IP上网

    一家之言,希望能帮你解决问题.此处更多为我自留备忘. 环境: win7:机安装支持桥接模式的服务. vmware12 ubutu 14.01 注意事项(此处坑多): 1.networking rest ...

  9. jstl 小总结 以及 jstl fn

    1.1.1 JSTL的使用 JSTL是JSP标准标签库.结合EL替换传统页面的<%%> * JSTL如果不会用.也是可以使用<%%>.但是一般在大公司使用JSTL.进入小公司. ...

  10. java26

    1:网络编程(理解)    (1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享    (2)网络编程模型    (3)网络编程的三要素        A:IP地址           ...