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」凸多边形的划分
不能说哪不同吧,只能说一模一样