能量项链 (区间DP)

能量项链 (区间DP)

问题引入

能量项链 洛谷 P1063

思路

诸如此类不能线性规划的问题要用到区间DP,区间DP一般就是三层循环,第一层表示区间长度(本题即n),第二层枚举起点并根据第一层区间长度算出区间终点,第三层便在当前区间内枚举决策(即哪两个合并)

本题由于是环,还需破环为列,可以开两倍大的数组,即a[i]=a[i+n],便可在第n颗珠子时求到第1颗珠子的头标记(也即第n颗珠子的尾标记)

合并珠子即合并左珠dp[i][k]和右珠dp[k+1][j],释放能量a[i]*a[k+1]*a[j+1](注意a[i]存放的是第i颗珠子的头标记,所以a[k+1]才是第k个珠子的尾标记)

例码

#include <iostream> 
#define MAXN 202
#define MAX(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n,a[MAXN],dp[MAXN][MAXN],ans;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i],a[i+n]=a[i];
    for(int len=2;len<=n;len++)//枚举区间长度
        for(int i=1;i+len-1<n*2;i++){//枚举区间起点
            int j=i+len-1;//区间终点
            for(int k=i;k<j;k++)//枚举决策
                dp[i][j]=MAX(dp[i][j], dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1]);
        }
    for(int i=1;i<=n;i++)//枚举可能的答案
        ans=MAX(dp[i][i+n-1],ans);
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/santiego/p/9462588.html
今日推荐