能量项链

咕咕咕

 

(动态规划不好..我从头学..)

(动态规划很暴力的感觉,,,只要暴力就完了?母鸡唉)

 

题解

区间动规

重点就是将整体划分为区间,小区间之间合并获得大区间

状态转移方程的推导如下

一、将珠子划分为两个珠子一个区间时,这个区间的能量=左边珠子*右边珠子*右边珠子的下一个珠子

二、区间包含3个珠子,可以是左边单个珠子的区间+右边两珠子的区间,或者左边两珠子的区间右边+单个珠子的区间

即,先合并两个珠子的区间,释放能量,加上单个珠子区间的能量(单个珠子没有能量。。)

Energy=max(两个珠子的区间的能量+单个珠子区间的能量,单个珠子的区间的能量+两个珠子的区间的能量 )

三、继续推4个珠子的区间,5个珠子的区间。

于是可以得到方程:Energy=max(不操作的能量,左区间合并后的能量+右区间合并后的能量+两区间合并产生能量)

两区间合并后产生的能量=左区间第一个珠子*右区间第一个珠子*总区间后面的一个珠子

 

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
inline int read()
{
    int sum = 0,p = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
            p = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        (sum *= 10) += ch - '0';
        ch = getchar();
    }
    return sum * p;
}
const int N = 109;
ll n,val[N * 2];
ll dp[N * N][N * N],ans;
int main()
{
    n = read();
    for(int i = 1; i <= n; i++)
    {
        val[i] = read();
        val[i + n] = val[i];
    }
    for(int i = 2; i <= 2 * n; i++)
    {
        for(int j = i - 1; j >= 1 && i - j < n; j--)
        {
            for(int k = j; k < i; k++)
                dp[j][i] = max(dp[j][i],dp[j][k] + dp[k + 1][i] + val[j] * val[k +1] * val[i + 1]);
            ans = max(ans,dp[j][i]);
        }
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

(抄题解快乐...)

 

posted @ 2019-08-14 15:07  darrrr  阅读(253)  评论(0编辑  收藏  举报