USTCOJ 1264 Longest ‘V’ sequence

题目链接:http://acm.ustc.edu.cn/ustcoj/problem.php?id=1264



TAG: 简单DP

题意 给你一个N*M【N,M<=1000】的 0 1矩阵,求这个矩阵中 1 能组成的最长的 ' V ' 形的长度。【两边不一定要一样长,但是一定要有个转折点,而且开口必须朝上】



做两个初始化,从第一行和第一列的数开始,往右下方递推,能递推出每一个数往左上角延伸的最长长度dp1[i][j]。

然后从第一行和最后一列开始 往左下方递推,能递推出每一个数往右上角延生的最长长度dp2[i][j]。

然后枚举每个点,搜出max(dp1[i][j]+dp2[i][j]-1),但是有个前提条件 dp1[i][j]>1&&dp2[i][j]>1。

代码如下:

//2012_E
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>

using namespace std;

#define PN printf("\n");

char chrn;
#define SCRN while(scanf("%c",&chrn) && chrn!='\n');
int num[1002][1002];
int res[1002][1002];
int n,m;
int res2[1002][1002];
void update1(int x,int y)
{
    res[x][y]=num[x][y];
    x++;
    y++;
    while(x<n&&y<m)
    {
       if(num[x][y]==0)
          res[x][y]=0;
       else
          res[x][y]=res[x-1][y-1]+1;
       x++;y++;
    }
}
void update2(int x,int y)
{
    res2[x][y]=num[x][y];
    x++;y--;
    while(x<n&&y>=0)
    {
       if(num[x][y]==0)
          res2[x][y]=0;
       else
          res2[x][y]=res2[x-1][y+1]+1;
       x++;y--;
    }
}
int main()
{
    int t;
   // freopen("E.txt","r",stdin);
   // freopen("E.out","w",stdout);
    for(scanf("%d",&t);t;t--)
    {
        memset(num,0,sizeof(num));
        memset(res,0,sizeof(res));
        memset(res2,0,sizeof(res2));
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
           for(int j=0;j<m;j++)
              scanf("%d",&num[i][j]);
        for(int i=0;i<n;i++)
           update1(i,0);
        for(int i=1;i<m;i++)
           update1(0,i);
        for(int i=0;i<m;i++)
           update2(0,i);
        for(int i=0;i<n;i++)
           update2(i,m-1);
        int MAX=0;
        for(int i=0;i<n;i++)
           for(int j=0;j<m;j++)
           {
              if(res[i][j]<=1||res2[i][j]<=1)
                 continue;
              MAX=max(MAX,res[i][j]+res2[i][j]-1);
            }
        if(MAX==0)
           puts("-1");
        else 
        printf("%d\n",MAX);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值