Comet OJ – Contest #6 – B – 雙倍快樂(多程序dp)
阿新 • • 發佈:2021-01-15
技術標籤:動態規劃
https://www.cometoj.com/contest/48/problem/B?problem_id=2278
同時進行兩個互不干涉的dp並將兩個dp的結果合併起來,可以解決很多經典的dp問題。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e2 + 5, inf = 0x3f3f3f3f;
int a[maxn], dp[maxn][maxn];
//dp[i][j],結尾靠前的子序列的結尾是第i個,結尾靠後的子序列的結尾是第j個
//列舉每個數,加到子序列的後面
//規定j比i後,j之前的都考慮完了
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i];
int ans = 0;
//序列可以為空,所以i從0開始列舉
for (int i = 0; i <= n; ++i){
for (int j = i + 1; j <= n; ++j){
//因為是直接列舉k並用dp[i][j]更新,所以dp[i][j]要初始化一下
dp[i][j] = max(dp[i][j], a[i] + a[j]);
ans = max(ans, dp[i][j]);
for (int k = j + 1; k <= n; ++k){
//不管k是加到i後面還是j後面,k都會成為最靠後的序列,原來的i或j成為靠前的序列
if (a[k] >= a[j]) dp[i][k] = max(dp[i][k], dp[i][j] + a[k]);
if (a[k] >= a[i]) dp[j][k] = max(dp[j][k], dp[i][j] + a[k]);
}
}
}
cout << ans << endl;
return 0;
}