1. 程式人生 > 其它 >Comet OJ – Contest #6 – B – 雙倍快樂(多程序dp)

Comet OJ – Contest #6 – B – 雙倍快樂(多程序dp)

技術標籤:動態規劃

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; }