P1063 能量项链

联系:区间DP

P1063 能量项链

题解

区间DP板子题

f[ i ][ j ] 从第 i 颗珠子到第  j 颗珠子合并起来的最大能量

在读入的时候现将珠子们先制一遍放到后面,断环成链
转移就枚举最后一步聚合的位置即可

状态转移方程:

f[ i ][ j ] = max( f[ i ][ j ]  ,  f[ i ][ k ] + f[ k+1 ][ j ] + head[ i ] * tail[ k ] * tail[ j ] )

最优答案可能是之前就找到的,也可能是对于不同的断点k转移来的,左右取最优,然后合并左右

初始化    f [ i ] [ j ] = 0 

ans也要二倍区间长取最优

时间复杂度 O(8n3

代码

#include<bits/stdc++.h>

using namespace std;

int n,head[205],tail[205];
int f[205][205],ans=0;
//初始化默认为0了 

inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

int main()
{
    n=read();
    for(int i=1;i<=n;i++)  //环变链 
    {
        head[i]=read();
        head[i+n]=head[i];
    }
    for(int i=1;i<2*n;i++)  //串起来 
    {
        tail[i]=head[i+1];
    }  
    tail[2*n]=head[1];
    
    for(int l=2;l<=n;l++) //区间长 
      for(int i=1;i<=2*n-l+1;i++)  //起点 
      {
          int j=i+l-1;  //终点 
          for(int k=i;k<j;k++)  //断点 
          f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+head[i]*tail[k]*tail[j]);
      }
    
    //二倍区间求最值 
    for(int i=1;i<=n;i++) ans=max(ans,f[i][i+n-1]);
    
    printf("%d
",ans);
    
    return 0;
}
原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11130345.html