#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define pb push_back
#define mk make_pair
#define F first
#define S second
#define ALL(x) x.begin(), x.end()
using namespace std;
using PQ = priority_queue<int, vector<int>, greater<int>>;
const int INF = 2e18;
const int maxn = 1e6 + 5;
const int M = 1e9 + 7;
int n;
int h[maxn], v[maxn], dp[maxn], dom[maxn];
int mx[maxn];
void init () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> h[i];
for (int i = 1; i <= n; i++) cin >> v[i];
}
void solve () {
stack<int> stk;
stack<int> stk2;
for (int i = 1; i <= n; i++) {
// dom[i]: h[i] 支配的區間的 dp 值 max
// mx[i]: 從 1..i 有被支配的 index 的 dp 值取 max
// 不能支配跟 h[i] 一樣大的, 這樣會造成 h[j] 是 [j..i] 的最大值, 中間並沒有峰
while (stk.size () && h[stk.top()] < h[i]) {
// 支配 stk.top
dom[i] = max ({dom[i], dom[stk.top()], dp[stk.top()]});
// 記得也要 max 到 dp[stk.top()] 因為 dom[j] 不會包含 dp[j]
stk.pop ();
}
// 找上一個比 h[i] strictly greater 的
while (stk2.size () && h[stk2.top()] <= h[i]) {
stk2.pop ();
}
if (stk.empty ()) {
dp[i] = v[i];
mx[i] = dom[i];
}
else {
int ret = 0;
if (stk2.size()) ret = mx[stk2.top()]; // stk2.top: 第一個比 h[i] 大的
mx[i] = max (mx[stk.top()], dom[i]); // 大於等於他的 + 他支配的
dp[i] = ret + v[i];
}
stk.push (i);
stk2.push (i);
}
cout << *max_element (dp + 1, dp + n + 1) << "\n";
}
signed main() {
// push stack
// ios::sync_with_stdio(0);
// cin.tie(0);
int t = 1;
//cin >> t;
while (t--) {
init();
solve();
}
}
題解
給你一套方程組如下,其中模數( k_i )不一定互質,求出最小正整數解 x ,如果沒有則輸出 -1
Aug 2, 2023{%hackmd @ioncamp/__style %} 題目 給 $n,k,c[1]\sim c[k]$ 代表 $a$ 出現 $c[1]$ 次,$b$ 出現 $c[2]$ 次... $\sum\limits_{i=1}^k c[i]=n$ 這些 $1\sim k$ 組成了一個長度為 $n$ 的字串
Dec 1, 2022{%hackmd @ioncamp/__style %} 題目 構造一個 $1..n$ 的排列使得他的 最長單調子序列 恰好長度為 $k$ 最長單調子序列 是指這個子序列單調遞增或單調遞減 想法
Nov 30, 2022{%hackmd @ioncamp/__style %} outline outline init 加法 減法 乘法 除法
Nov 1, 2022or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up