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 }

 

posted @ 2021-02-10 10:58  acmloser  阅读(95)  评论(0编辑  收藏  举报