区间dp学习笔记

因为学习区间dp之前我会floyd,所以并不难掌握

dp[i][j]=max/min(dp[i][j],dp[i][k]+dp[k][j])

石子合并:https://www.luogu.org/problemnew/show/P1880

 1 #include <bits/stdc++.h>
 2 #define inf 1e7
 3 #define lll long long int
 4 #define void inline void
 5 using namespace std;
 6 int n,end,dp[500][500],a[1000],sum[1000],dp1[500][500],minn=912333,maxx=-1;
 7 int main(){
 8 ios::sync_with_stdio(0);
 9 memset(dp,-999999,sizeof(dp));
10 memset(dp1,9999999,sizeof(dp1));//求最大值和最小值时应记得赋初值
11 cin>>n;
12 for(int i=1;i<=n;i++) 
13 {
14     cin>>a[i];
15     sum[i]=sum[i-1]+a[i];
16     dp[i][i]=0;    //这里是在设置边界 后面k是可以=i的
17 dp1[i][i]=0;
18 }
19 for(int i=1;i<=n;i++) 
20 {
21     sum[i+n]=sum[i+n-1]+a[i];
22     dp[i+n][i+n]=0;        
23     dp1[i+n][i+n]=0;//这里是在设置边界 后面k是可以=i的
24 
25 }
26  for(int i=1;i<=n;i++){
27      for(int j=1;j+i<=n*2;j++){//关于为什么是2*n,其实这是一个环,我们需要破环成链
28          end=i+j;
29          for(int k=j;k<end;k++){
30          dp[j][end]=max(dp[j][end],dp[j][k]+dp[k+1][end]+sum[end]-sum[j-1]);
31          dp1[j][end]=min(dp1[j][end],dp1[j][k]+dp1[k+1][end]+sum[end]-sum[j-1]);//dp转移方程
32          }
33      }
34  }
35  for(int i=1;i<=n;i++){
36      minn=min(minn,dp1[i][i+n-1]);但最后还是n的长度,我们可以理解成为n条链的最大值/最小值
37      maxx=max(maxx,dp[i][i+n-1]);
38  }
39  cout<<minn<<endl<<maxx;
40 return 0;
41 }

区间dp要想学好,建议学习floyd

posted @ 2019-03-10 09:16  spytc  阅读(276)  评论(0编辑  收藏  举报