1036 凸多边形的划分 __128int高精度 区间DP
链接:https://ac.nowcoder.com/acm/problem/50500
来源:牛客网
题目描述
输入描述:
输入第一行为顶点数N
第二行依次为顶点1至顶点N的权值。
输出描述:
输出仅一行,为这些三角形顶点的权值乘积和的最小值。
备注:
对于100%100 \%100%的数据,有N≤50N \leq 50N≤50,每个点权值小于10910^9109。
分析:
可以从小区间推到大区间,所以想到区间DP
设dp[i][j] 表示的是以i,j为底边的最小凸多边形划分权值。
具体是:假设一开始连接i节点和j节点,得到i,j这条边,然后对于这之间的所有三角形已经划分好了,
所以状态转移方程式:dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j] + a[i] * a[j] * a[k]); k 是i和j之间的所有节点。
对于区间DP,len 要从3开始,让len小于3的直接等于0就可以了,因为这时候分不出三角形。
然后就是__128的高精度,这种高精度赋值设__128 c = 1; f[i][j] = c * (1e18) * 1e18;
//-------------------------代码----------------------------
//#define int LL
__int128 f[55][55];
int a[55];
void print(__int128 x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
}
void solve()
{
int n;
cin>>n;
fo(i,1,n) {
cin>>a[i];
}
__int128 c=1;
for(int len =3;len<=n;len++)
{
for(int l=1;l+len-1<=n;l++)
{
int r=l+len-1;
f[l][r]=c * (1e18) * (1e18);
for(int k=l+1;k<r;k++)
{
f[l][r]=min(f[l][r],f[l][k]+f[k][r]+c*a[l]*a[k]*a[r]);
}
}
}
print(f[1][n]);
}
signed main(){
clapping();TLE;
// int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}
/*样例区
*/
//------------------------------------------------------------