DP模板【洛谷P1880】
阿新 • • 發佈:2019-01-23
經典的石子合併題目,不多說了,這個是環形,其實和鏈一樣,只不過要延長一段。
本質上是個區間DP
(1)列舉區間長度
(2)列舉起點,算出終點
(3)列舉斷點
直接上程式碼:
#include <bits/stdc++.h> using namespace std; const int maxn = 210; const int INF = 1e9+7; int v[maxn]; int f[maxn][maxn]; int dp[maxn][maxn]; void init() { memset(v,0,sizeof(v)); memset(dp,0,sizeof(dp)); memset(f,0,sizeof(f)); } int main() { int n; cin>>n; init(); for(int i=1;i<=n;i++) { cin>>v[i]; v[i+n] = v[i]; } for(int i=1;i<=2*n;i++) { v[i]+=v[i-1]; } for(int len = 2;len<=2*n;len++) { for(int i=1;i+len-1<=2*n;i++) { int j = i+len-1; dp[i][j] = INF; f[i][j] = 0; for(int k=i;k<j;k++) { dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+v[j]-v[i-1]); f[i][j] = max(f[i][j],f[i][k]+f[k+1][j]+v[j]-v[i-1]); } } } int mx = 0; int mn = INF; for(int i=2;i<=n;i++) { mx = max(mx,f[i][i+n-1]); mn = min(mn,dp[i][i+n-1]); } cout<<mn<<endl; cout<<mx<<endl; return 0; }
模板題,可能是DP裡面除了揹包問題之外第二簡單的題了吧。