P1063 [NOIP2006 提高组] 能量项链

原题链接

题解

1.拆环成链
2.最后一颗留下来的珠子一定是的头标记一定是某个原珠子\(A\)的头标记,尾标记一定是珠子\(A\)右边n个单位的珠子的尾标记
3.对任意最大值而言,最后一颗一定是某两个珠子的合并后产生的,所以我们可以在区间内断点遍历

\(Code\)

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int l,r;
}a[205];
int f[205][205]={0};//f代表区间[l,r]内珠子合并成一颗时的最大值
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].l;
        a[i+n].l=a[i].l;//拆环成链
    }

    for(int i=1;i<2*n;i++) a[i].r=a[i%(2*n)+1].l;

    int ans=0;
    for(int s=1;s<=n;s++)
    {
        for(int d=2;d<=n;d++)
            for(int l=s;l<=s+n-d;l++)
            {
                int r=l+d-1;
                for(int mid=l;mid<r;mid++)  f[l][r]=max(f[l][r],a[l].l*a[mid].r*a[r].r+f[l][mid]+f[mid+1][r]);//当l=r时为零,因为这个区间没有珠子合并过
//注意细节,从小区间推导到大区间时加法不是乘法
            }
        ans=max(ans,f[s][s+n-1]);
    }

    cout<<ans<<endl;
    return 0;
}

posted @ 2024-01-27 11:59  纯粹的  阅读(39)  评论(0)    收藏  举报