力扣2713 2024.6.19

训练师马文發表於2024-06-19

原題網址:此處為連結

個人難度評價:1700

分析:
DP順序很重要,從大數遞推到小數保證了不會每次都是最優子結構而不會有後效性。
開了個map來方便二分大於當前數的最小數,狀態轉移方程顯然,記h[x]與l[y]表示第x行小於當前值的最優和第y列小於當前值的最優:
dp[x][y] = max(f[x], l[y])
注意h和l每次也要更新

原始碼:

// 2713
#include <bits/stdc++.h>
#define pp pair<int, pair<int, int>>
using namespace std;
const int INF = 0x3f3f3f3f;

class Solution {
public:

    int maxIncreasingCells(vector<vector<int>>& mat) {
        int n = mat.size();
        int m = mat[0].size();
        deque<pp> now;
        for (int i=0; i<n; i++){
            for (int j=0; j<m; j++){
                now.push_back({-mat[i][j], {i+1, j+1}});
            }
        }
        sort(now.begin(), now.end());
        map<int, int> dph[n+1], dpl[m+1];
        int f[n+1][m+1];
        memset(f, 0 ,sizeof(f));
        int ans = 0;
        int v, x, y;
        while (now.size()){
            v = -now.front().first;
            x = now.front().second.first;
            y = now.front().second.second;
            now.pop_front();
            if (dph[x].empty()){
                f[x][y] = max(f[x][y], 1);
                dph[x][v] = 1;
            }
            else{
                f[x][y] = max(f[x][y], dph[x].upper_bound(v)->second+1);
            }
            if (dpl[y].empty()){
                f[x][y] = max(f[x][y], 1);
                dpl[y][v] = 1;
            }
            else{
                f[x][y] = max(f[x][y], dpl[y].upper_bound(v)->second+1);
            }
            dph[x][v] = max(dph[x][v], f[x][y]);
            dpl[y][v] = max(dpl[y][v], f[x][y]);
            ans = max(ans, f[x][y]);
        }
        return ans;
    }
};

相關文章