题目链接
LOJ #10149. 「一本通 5.1 例 3」凸多边形的划分
解题思路
这道题显而易见是一道区间DP
我们将所有点逆时针编号
设
f
[
l
]
[
r
]
f[l][r]
f[l][r]表示从
l
l
l到逆时针
r
r
r这一部分的图形(一个以
l
l
l、
r
r
r和路径上其他点组成的多边形)所能达到的最大权值和。
易得:
f
[
i
]
[
i
+
1
]
=
0
,
e
l
s
e
f
[
i
]
[
j
]
=
I
N
F
f[i][i+1]=0,else \ f[i][j] = INF
f[i][i+1]=0,else f[i][j]=INF
f
[
i
]
[
j
]
=
M
a
x
{
f
[
i
]
[
j
]
,
f
[
i
]
[
k
]
+
f
[
k
]
[
j
]
+
w
[
i
]
∗
w
[
j
]
∗
w
[
k
]
}
f[i][j]=Max\{f[i][j],f[i][k]+f[k][j]+w[i]*w[j]*w[k]\}
f[i][j]=Max{f[i][j],f[i][k]+f[k][j]+w[i]∗w[j]∗w[k]},其中k为断点。
至于这是个环,破环成链是基操= =.
另外,看这题的数据范围,要写高精跑不了了。
详细代码
#define USEFASTERREAD 1
#define rg register
#define inl inline
#define DEBUG printf("qwq\n")
#define DEBUGd(x) printf("var %s is %lld", #x, ll(x))
#define DEBUGf(x) printf("var %s is %llf", #x, double(x))
#define putln putchar('\n')
#define putsp putchar(' ')
#define Rep(a, s, t) for(rg int a = s; a <= t; a++)
#define Repdown(a, t, s) for(rg int a = t; a >= s; a--)
typedef long long ll;
typedef unsigned long long ull;
#include<cstdio>
#if USEFASTERREAD
char In[1 << 20], *ss = In, *tt = In;
#define getchar() (ss == tt && (tt = (ss = In) + fread(In, 1, 1 << 20, stdin), ss == tt) ? EOF : *ss++)
#endif
namespace IO {
inl void RS() {freopen("test.in", "r", stdin), freopen("test.out", "w", stdout);}
inl ll read() {
ll x = 0, f = 1; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + int(ch - '0');
return x * f;
}
inl void write(ll x) {
if(x < 0) {putchar('-'); x = -x;}
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
inl void writeln(ll x) {write(x), putln;}
inl void writesp(ll x) {write(x), putsp;}
}
using namespace IO;
template<typename T> inline T Max(const T& x, const T& y) {return y < x ? x : y;}
template<typename T> inline T Min(const T& x, const T& y) {return y < x ? y : x;}
template<typename T> inline void Swap(T& x, T& y) {T tmp = x; x = y; y = tmp;}
template<typename T> inline T Abs(const T& x) {return x < 0 ? -x : x;}
#include<cstring>
const int MAXN = 105;
const ll INF = 0x3f3f3f3f3f3f3f3f;
namespace GJD {
const int MAXLEN = 505;
const int NN = 100000000, N = 8;
struct Bigint {
int len;
ll A[MAXLEN / N + 5];
bool flag;//is inf
Bigint(ll x = 0) {
memset(A, 0x00, sizeof A);
flag = false;
if(x == 0) {
len = 1; return;
}
len = 0;
while(x) {
A[len++] = x % NN;
x /= NN;
}
}
Bigint& SetINF() {flag = 1; return *this;}
ll operator [] (const int& k)const {return A[k];}
ll& operator [] (const int& k) {return A[k];}
Bigint operator + (const Bigint& B)const {
if(flag || B.flag) return Bigint().SetINF();
Bigint C;
C.len = Max(len, B. len);
for(rg int i = 0; i < C.len; i++) {
C[i] += A[i] + B[i];
if(C[i] >= NN) {
C[i + 1]++;
C[i] -= NN;
}
}
if(C[C.len]) C.len++;
while(C[C.len - 1] == 0 && C.len > 1) C.len--;
return C;
}
Bigint operator * (const Bigint& B)const {
Bigint C;
C.len = len + B.len - 1;
for(rg int i = 0; i < len; i++)
for(rg int j = 0; j < B.len; j++)
C[i + j] += A[i] * B[j];
for(rg int i = 0; i < C.len; i++)
C[i + 1] += C[i] / NN, C[i] %= NN;
if(C[C.len]) C.len++;
while(C[C.len - 1] == 0 && C.len > 1) C.len--;
return C;
}
bool operator < (const Bigint& B)const {
if(flag) return false;
if(B.flag) return true;
if(len != B.len) return len < B.len;
for(rg int i = len - 1; i >= 0; i--)
if(A[i] != B[i]) return A[i] < B[i];
return false;
}
void Write() {
write(A[len - 1]);
for(rg int i = len - 2; i >= 0; i--) {
for(rg int j = NN / 10; A[i] < j; j /= 10) putchar('0');
if(A[i]) write(A[i]);
}
}
};
}
using GJD::Bigint;
int N;
ll w[MAXN];
Bigint f[MAXN][MAXN];
Bigint ans = Bigint().SetINF();
int main() {
//RS();
N = read();
for(rg int i = 1; i <= N; i++) w[i + N] = w[i] = read();
for(rg int i = 1; i <= 2 * N; i++)
for(rg int j = 1; j <= 2 * N; j++) f[i][j].SetINF();
for(rg int i = 1; i <= 2 * N; i++) f[i][i + 1] = 0;
for(rg int len = 3; len <= N; len++)
for(rg int l = 1; l + len - 1 <= 2 * N; l++) {
int r = l + len - 1;
for(rg int i = l + 1; i < r; i++)
f[l][r] = Min(f[l][r], f[l][i] + f[i][r] + Bigint(w[l] * w[r]) * Bigint(w[i]));
}
for(rg int i = 1; i + N - 1 <= 2 * N; i++)
ans = Min(f[i][i + N - 1], ans);
ans.Write();
return 0;
}