HihoCoder 1469 dp

一道不太明显的dp,dp[i][j]的含义是,以i,j为右下角的福字的大小。
首先进行预处理,两个二维数组。shang[i][j]表示从座标ij的元素开始向上寻找,能找到多少个元素使他们都满足map[i-1][j] + 1 == map[i][j],比如这个

1 2 3
2 3 4
3 5 5

他的shang数组就是

1 1 1
2 2 2
3 3 3

同理,再构建一个左数组。
然后我们就可以找到这样的转移方程

            if(map[i][j] == map[i-1][j-1] + 2){
                dp[i][j] = min(dp[i-1][j-1]+1,min(shang[i][j],zuo[i][j]));
            }

ac代码

#include <iostream>
#include <math.h>
#include <iomanip>
#include <string>
#include <cstdio>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
#define N 2010
#define M 998244353
#define ll long long
using namespace std;

int n;
int map[N][N];
int shang[N][N],zuo[N][N];
int dp[N][N];
int main() {
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            scanf("%d",&map[i][j]);
        }
    }
    int tmp = 1;
    for(i=1;i<=n;i++){
        tmp = 1;
        zuo[i][1] = tmp;
        for(j=2;j<=n;j++){
            if(map[i][j] == map[i][j-1] + 1){
                tmp++;
                zuo[i][j] = tmp;
            }else{
                tmp = 1;
                zuo[i][j] = tmp;
            }
        }
    }


    for(j=1;j<=n;j++){
        tmp = 1;
        shang[1][j] = tmp;
        for(i=2;i<=n;i++){
            if(map[i][j] == map[i-1][j] + 1){
                tmp++;
                shang[i][j] = tmp;
            }else{
                tmp = 1;
                shang[i][j] = tmp;
            }
        }
    }
    for(i=1;i<=n;i++){
        dp[i][1] = dp[1][i] = 1;
    }
    int ans = 0;
    for(i=2;i<=n;i++){
        for(j=2;j<=n;j++){
            if(map[i][j] == map[i-1][j-1] + 2){
                dp[i][j] = min(dp[i-1][j-1]+1,min(shang[i][j],zuo[i][j]));
                ans = max(ans,dp[i][j]);
            }else
            {
                dp[i][j] = 1;
                ans = max(ans,dp[i][j]);
            }
             
        }
    }
    printf("%d\n",ans);
    return 0;
}

一开始想的是按照dp[i-1][j]或者dp[i][j-1]构造转移方程,后来发现很麻烦而且没有必要。
这道题的数据比较松,有些错误的转移方程也可以跑过。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章