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]構造轉移方程,後來發現很麻煩而且沒有必要。
這道題的數據比較松,有些錯誤的轉移方程也可以跑過。

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