AcWing 1069. 凸多边形的划分
考察:区间DP
这道题是能量项链的扩展...
思路:
在多边形内任取一条边,这条边一定属于某个三角形,划分情况随着三角形的顶点位置变化而变化.当选定一个三角形时,多边形被三角形分为两个部分,这两个部分是完全独立的,即f[i][j]表示的是i,j形成的多边形内划分三角形的情况,f[i][j] = f[i][k]+f[k][j]+a[i]*a[j]*a[k]状态转移方程与能量项链本质相同.k是三角形顶点.
注意:
本题需要使用高精度
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 typedef long long ll; 7 const int N = 55,M = 55; 8 int a[N]; 9 ll f[N][N][M]; 10 void mul(ll s[],ll b) 11 { 12 ll t = 0,c[M]; 13 memset(c,0,sizeof c); 14 for(int i=0;i<M;i++) 15 { 16 t+=s[i]*b; 17 c[i] = t%10; 18 t/=10; 19 } 20 memcpy(s,c,sizeof c); 21 } 22 void add(ll s[],ll b[]) 23 { 24 ll t = 0,c[M]; 25 memset(c,0,sizeof c); 26 for(int i=0;i<M;i++) 27 { 28 t += s[i]+b[i]; 29 c[i] = t%10; 30 t/=10; 31 } 32 memcpy(s,c,sizeof c); 33 } 34 int cmp(ll b[],ll c[]) 35 { 36 for(int i=M-1;i>=0;i--) 37 if(b[i]>c[i]) return 1; 38 else if(b[i]<c[i]) return -1; 39 return 0; 40 } 41 void MyPrint(ll a[]) 42 { 43 int t = M-1; 44 while(!a[t]&&t) t--; 45 for(int i=t;i>=0;i--) printf("%lld",a[i]); 46 printf("\n"); 47 } 48 int main() 49 { 50 int n; 51 scanf("%d",&n); 52 ll tmp[M]; 53 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 54 for(int len=3;len<=n;len++) 55 for(int l=1;l+len-1<=n;l++) 56 { 57 int r = l+len-1; f[l][r][M-1] = 1; 58 for(int k=l+1;k<r;k++) 59 { 60 memset(tmp,0,sizeof tmp); 61 tmp[0] = 1; 62 mul(tmp,a[l]); 63 mul(tmp,a[r]); 64 mul(tmp,a[k]); 65 add(tmp,f[l][k]); add(tmp,f[k][r]); 66 if(cmp(tmp,f[l][r])==-1) memcpy(f[l][r],tmp,sizeof tmp); 67 } 68 } 69 MyPrint(f[1][n]); 70 return 0; 71 }