原題網址:此處為連結
個人難度評價: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;
}
};