Analysis
区间dp+记录路径
用dfs倒着找倒数第几次合并
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define maxn 310 6 #define INF 2139062143 7 using namespace std; 8 inline int read() 9 { 10 int x=0; 11 bool f=1; 12 char c=getchar(); 13 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 14 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 15 if(f) return x; 16 return 0-x; 17 } 18 inline void write(int x) 19 { 20 if(x<0){putchar('-');x=-x;} 21 if(x>9)write(x/10); 22 putchar(x%10+'0'); 23 } 24 int n; 25 int a[maxn],dp[maxn][maxn],path[maxn][maxn],ans[maxn]; 26 inline void print(int l,int r,int step,int num) 27 { 28 if(l==r) return; 29 int mid=path[l][r]; 30 if(step==num) 31 { 32 write(mid); 33 printf(" "); 34 } 35 print(l,mid,step+1,num); 36 print(mid+1,r,step+1,num); 37 } 38 int main() 39 { 40 n=read(); 41 for(int i=1;i<=n;i++) a[i]=read(); 42 for(int len=2;len<=n;len++) 43 { 44 for(int i=1;i<=n;i++) 45 { 46 int j=i+len-1; 47 if(j>n) break; 48 for(int k=i;k<j;k++) 49 { 50 if(dp[i][k]+dp[k+1][j]+(a[i]+a[j])*a[k]>dp[i][j]) 51 { 52 dp[i][j]=dp[i][k]+dp[k+1][j]+(a[i]+a[j])*a[k]; 53 path[i][j]=k; 54 } 55 } 56 } 57 } 58 write(dp[1][n]); 59 printf(" "); 60 for(int i=1;i<n;i++) print(1,n,1,i); 61 return 0; 62 } 63 64 /* 65 7 66 1 2 3 4 5 6 7 67 */
请各位大佬斧正(反正我不认识斧正是什么意思)