凸多边形三角划分

传送门 (LOJ升级版)

这道题虽然是基础的区间DP,但是还是很值得一说的。

我们用dp[i][j]表示第i个点到第j个点划分的最大值。注意我们只枚举了两个端点,第三个顶点是我们枚举的那个k,之后发现k这个顶点可以把整个区间分成两块,我们就可以进行区间DP了。

只不过这道题要使用高精度。需要自己重载一下,对于赋INF值的话,我们直接把长度设为极大值即可。(好像还能用int128过)

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('
')

using namespace std;
typedef long long ll;
const int M = 10005;
const ll INF = 1000000009;

ll read()
{
    ll ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
    if(ch == '-') op = -1;
    ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
    ans *= 10;
    ans += ch - '0';
    ch = getchar();
    }
    return ans * op;
}

struct big
{
   int f[105],len;
   big()
   {
      memset(f,0,sizeof(f)),len = 0;
   }
   void modi(ll g)
   {
      if(g >= INF)
      {
     len = 50;
     return;
      }
      while(g) f[len++] = g % 10,g /= 10;
      while(!f[len] && len > 0) len--;
   }
   big operator * (const big &g) const
   {
      big c;
      c.len = len + g.len + 1;
      rep(i,0,len)
      rep(j,0,g.len) c.f[i+j] += f[i] * g.f[j];
      rep(i,0,c.len-1) c.f[i+1] += c.f[i] / 10,c.f[i] %= 10;
      while(!c.f[c.len] && c.len > 0) c.len--;
      return c;
   }
   big operator + (const big & g) const
   {
      big c;
      c.len = max(len,g.len) + 1;
      rep(i,0,c.len) c.f[i] = f[i] + g.f[i];
      rep(i,0,c.len-1) c.f[i+1] += c.f[i] / 10,c.f[i] %= 10;
      while(!c.f[c.len] && c.len > 0) c.len--;
      return c;
   }
   void print()
   {
      per(i,len,0) printf("%d",f[i]);enter;
   }
}dp[105][105],a[105];

ll n,x;

big bmin(const big &a,const big &b)
{
   if(a.len != b.len) return (a.len < b.len) ? a : b;
   per(i,a.len,0) if(a.f[i] != b.f[i]) return (a.f[i] < b.f[i]) ? a : b;
   return a;
}

int main()
{
   n = read();
   rep(i,1,n) x = read(),a[i].modi(x);
   rep(L,2,n-1)
   {
      rep(i,1,n-L)
      {
     int j = i + L;
     dp[i][j].modi(INF);
     rep(k,i+1,j-1) dp[i][j] = bmin(dp[i][j],dp[i][k] + dp[k][j] + a[i] * a[j] * a[k]);
      }
   }
   dp[1][n].print();
   return 0;
}
原文地址:https://www.cnblogs.com/captain1/p/9892654.html