P1063 [NOIP2006 提高组] 能量项链

P1063 [NOIP2006 提高组] 能量项链

区间DP,和环形石子合并差不多,就是把加改成乘,枚举区间范围不同罢了。

先复制一遍数组,破环为链。

想想哪里不同?我们不要按题意模拟,看样例,无非就是三个数合并,一直合并到一个。但是我们还要考虑到环形的影响,区间长度最长不能到 \(n\) 就停, 应该到 \(n+1\),这样能把首尾接起来。然后再枚举左端点,确定右端点,值得注意的是枚举分割点的时候不能取到 \([l,r]\) 的端点,因为合并的三个数不能有重叠,不然不满足题目描述。

代码如下:

/*
Knowledge : Rubbish Algorithm
Work by :Gym_nastics
Time : O(AC)
*/
#include<bits/stdc++.h>
using namespace std;
const int M=205;

int read() {
    int x=0,f=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
    return f?-x:x;
}

int n,a[M],f[M][M];
signed main() {
   n=read();for(int i=1;i<=n;i++) a[i]=a[i+n]=read();
   for(int len=3;len<=n+1;len++){
       for(int l=1;l+len-1<=(n<<1);l++){
           int r=len+l-1;for(int k=l+1;k<r;k++)
           f[l][r]=max(f[l][r],f[l][k]+f[k][r]+a[l]*a[k]*a[r]);
       }
   }int ans=0;
   for(int i=1;i<=n;i++) ans=max(ans,f[i][i+n]);
   return printf("%d\n",ans),0;
}

类似题:
#10149. 「一本通 5.1 例 3」凸多边形的划分
不能说哪不同吧,只能说一模一样

posted @ 2022-03-19 09:00  Gym_nastics  阅读(83)  评论(0)    收藏  举报