P1880 [NOI1995]石子合并

zy嘤嘤嘤
这题,跟能量项链比较像哈,反正就是一个加,一个乘,但是,加法肯定是要比乘法简单的,so这题应该也要比能量项链简单(其实两题真的p区别都没有) 区间dp,三重循环,第一层区间长度l,第二层区间开始下标i,并求出结束下标j=i+l,第三层k由i到j-1,状态转移方程则为
dp1[i][j]=ma(dp1[i][k]+dp1[k+1][j]+sum[j]-sum[i-1],dp1[i][j])

dp2[i][j]=mi(dp2[i][k]+dp2[k+1][j]+sum[j]-sum[i-1],dp2[i][j])(一大一小)
而由于这题是个环(能量项链也是环),so将本题数据由n个扩展到2n个,最后搜索区间长度为n的最大及最小值
下面附上代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 int n;
 9 int a[305],sum[305],dp1[305][305],dp2[305][305];
10 
11 int ma(int a,int b){return a>b?a:b;}
12 int mi(int a,int b){return a<b?a:b;}
13 
14 int main(){
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++){
17         scanf("%d",&a[i]);
18         a[i+n]=a[i];
19         sum[i]=sum[i-1]+a[i];
20     }
21     for(int i=1;i<=n;i++){
22         sum[i+n]=sum[i+n-1]+a[i];
23     }
24     for(int l=1;l<n;l++){
25         for(int i=1,j=i+l;i<n+n&&j<n+n;i++,j=i+l){
26             dp2[i][j]=10000000;
27             for(int k=i;k<j;k++){
28                 dp1[i][j]=ma(dp1[i][k]+dp1[k+1][j]+sum[j]-sum[i-1],dp1[i][j]);
29                 dp2[i][j]=mi(dp2[i][k]+dp2[k+1][j]+sum[j]-sum[i-1],dp2[i][j]);
30             }
31         }
32     }
33     int ans1=0,ans2=10000000;
34     for(int i=1;i<=n;i++){
35         ans1=ma(ans1,dp1[i][n+i-1]);
36         ans2=mi(ans2,dp2[i][n+i-1]);
37     }
38     printf("%d\n%d\n",ans2,ans1);
39     return 0;
40 }

嘤嘤嘤新人开博鼓励一下吧~~

posted @ 2019-07-17 11:35  喵呜,颜儿ღ  阅读(109)  评论(0编辑  收藏  举报