P1880 [NOI1995]石子合并(区间DP)

题目链接:https://www.luogu.org/problemnew/show/P1880

题目大意:中文题目

具体思路:和上一篇的思路是差不多的,也是对于每一个小的区间进行处理,然后再归并到大区间上。

这里的递推式:dp[i][j]=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];

AC代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<cstring>
 4 using namespace std;
 5 # define ll long long
 6 # define inf 0x3f3f3f3f
 7 const int maxn = 4e2+100;
 8 const int mod =1e6;
 9 # define LL_inf 0x3f3f3f3f3f3f3f
10 int dp1[maxn][maxn];
11 int dp2[maxn][maxn];
12 int sum[maxn],a[maxn];
13 int main(){
14 int n;
15 scanf("%d",&n);
16 for(int i=1;i<=n;i++){
17 scanf("%d",&a[i]);
18 sum[i]=sum[i-1]+a[i];
19 a[i+n]=a[i];
20 }
21 for(int i=n+1;i<=2*n;i++){
22 sum[i]=sum[i-1]+a[i];
23 }
24 for(int i=1;i<=n;i++){
25 for(int j=1,pos=j+i;j<2*n&&pos<2*n;j++,pos=j+i){
26 dp1[j][pos]=inf;
27 for(int k=j;k<pos;k++){//注意这里不能等于,因为一个数的时候应该是按照0来算的
28 dp1[j][pos]=min(dp1[j][pos],dp1[j][k]+dp1[k+1][pos]+sum[pos]-sum[j-1]);
29 dp2[j][pos]=max(dp2[j][pos],dp2[j][k]+dp2[k+1][pos]+sum[pos]-sum[j-1]);
30 }
31 }
32 }
33 int minn=inf,maxx=0;
34 for(int i=1;i<=n;i++){
35 minn=min(minn,dp1[i][i+n-1]);
36 maxx=max(maxx,dp2[i][i+n-1]);
37 }
38 printf("%d\n%d\n",minn,maxx);
39 return 0;
40 }

 

posted @ 2019-03-14 16:10  Let_Life_Stop  阅读(180)  评论(0编辑  收藏  举报