dp——环形石子合并(区间dp)

环形的解决很巧妙

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <map>
 5 #include <set>
 6 #include <algorithm>
 7 #include <fstream>
 8 #include <cstdio>
 9 #include <cmath>
10 #include <stack>
11 #include <queue>
12 #define lson l,m,rt<<1
13 #define rson m+1,r,rt<<1|1
14 using namespace std;
15 const double Pi=3.14159265358979323846;
16 typedef long long ll;
17 const int MAXN=100+5;
18 const int dx[5]={0,0,0,1,-1};
19 const int dy[5]={1,-1,0,0,0};
20 const int INF = 0x3f3f3f3f;
21 const int NINF = 0xc0c0c0c0;
22 const ll mod=1e9+7;
23 
24 int a[MAXN*2],dp[MAXN*2][MAXN*2];int sum[MAXN*2];int df[MAXN*2][MAXN*2];
25 
26 int main()
27 {
28     int n;scanf("%d",&n);
29     memset(dp,0,sizeof(dp));
30     for(int i=1;i<=n;i++)
31     {
32         scanf("%d",&a[i]);
33         sum[i]=sum[i-1]+a[i];
34     }
35     for(int i=n+1;i<=n+n;i++)
36     {
37         a[i]=a[i-n];
38         
39         sum[i]=sum[i-1]+a[i]; 
40     }
41     for(int l=2;l<=n;l++)
42     {
43         
44         for(int i=1;i<=n+n;i++)
45         {
46             int j=l+i-1;
47             df[i][j]=INF;
48             if(j>n+n) continue;
49             for(int k=i;k<j;k++)
50             {
51                 dp[i][j]=max(dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1],dp[i][j]);
52                 df[i][j]=min(df[i][k]+df[k+1][j]+sum[j]-sum[i-1],df[i][j]);
53             }
54             
55         }
56     }
57     int ans1=0;
58     int ans2=INF;
59     for(int i=1;i<=n;i++)
60     {
61         int j=i+n-1;
62         if(j>n+n) break;
63         ans1=max(dp[i][j],ans1);
64         ans2=min(df[i][j],ans2);
65         
66     }
67     cout << ans2<<endl<<ans1<<endl;  
68     return 0;
69 }
View Code

 

posted @ 2019-03-09 19:13  Chuhanjing  阅读(258)  评论(0编辑  收藏  举报