zoukankan      html  css  js  c++  java
  • 能量项链 (区间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;
    }
    
  • 相关阅读:
    第十三周助教总结
    C语言I博客作业09
    第十二周助教总结
    C语言I博客作业08
    第十一周助教总结
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I作业07
    C语言I作业06
  • 原文地址:https://www.cnblogs.com/santiego/p/9462588.html
Copyright © 2011-2022 走看看