Codeforces Round 1009 (Div. 3)-G
点我写题
题意:与凸边形的划分题类似,只不过这次划分的三角形不能有共享边
思路:考虑区间dp[i][j],处理完i-j区间的划分最大值
转移:枚举的区间长度<3明显不用考虑,长度==3则只能构成一个三角形,答案就是三个点权值的乘积,len>3,考虑枚举的俩个端点,是否要构成一个三角形:
case1:如果不构成,则答案可以从dp[i+1][j-1]和dp[i][k]+dp[k+1][j]转移过来(k是区间i-j中的某个点)
case2:构成的话,则是可以从dp[i+1][k-1]+dp[k+1][j]+a[i]*a[k]*a[j]转移过来,(因为不能有共享边),然后注意一下边界情况即可
代码:
import java.util.*;
import java.io.*;
public class Main{
public static BufferedReader rd=new BufferedReader(new InputStreamReader(System.in));
public static BufferedWriter wd=new BufferedWriter(new OutputStreamWriter(System.out));
public static void solve()throws Exception{
String dr[]=rd.readLine().split(" ");
int n=Integer.parseInt(dr[0]);
int a[]=new int [n+10];
dr=rd.readLine().split(" ");
long dp[][]=new long [n+10][n+10];
for(int i=1;i<=n;i++) a[i]=Integer.parseInt(dr[i-1]);
for(int len=3;len<=n;len++){
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;
if(len==3){
dp[i][j]=a[i]*a[j]*a[i+1];
// wd.write(i+" "+j+" "+dp[i][j]+"\n");
continue;
}
dp[i][j]=dp[i+1][j-1];
for(int k=i;k<j;k++){
long tem=dp[i][k]+dp[k+1][j];
long tem2=0;
if(k>i) tem2=a[i]*a[k]*a[j]+dp[i+1][k-1]+dp[k+1][j-1];
dp[i][j]=Math.max(dp[i][j],Math.max(tem,tem2));
}
// wd.write(i+" "+j+" "+dp[i][j]+"\n");
}
}
wd.write(dp[1][n]+"\n");
}
public static void main(String args[])throws Exception{
int t=Integer.parseInt(rd.readLine());
while(t-->0){
solve();
wd.flush();
}
}
}