1 solutions
-
1
此题要点:
- 体会区间DP的思想(从小区间合并得到大区间);
- 状态的定义;
- 初始化的手段;
__int128
的用法要掌握。
#include <iostream> using namespace std; typedef __int128 LLL; const int N = 55; LLL a[N]; LLL f[N][N]; // f[i][j]表示凸多边形 (i,j) 的最小划分值 // __int128的输入输出。选你喜欢的背下来,熟练书写。更多写法请自行搜索。 ostream& operator << (ostream& out, LLL x) {...} void write(LLL x) {...} LLL read() {...} int main() { int n; cin >> n; for (int i = 1; i <= n; i++) a[i] = read(); for (int len = 3; len <= n; len++) // 状态:区间长度从3开始,2是没意义的。 for (int L = 1; L + len - 1 <= n; L++) { // 枚举区间左端点 int R = L + len - 1; // 为了避免初始化为无穷,就直接把 k==L+1 这种情况当作 f[L][R] 的初始值。 f[L][R] = f[L][L + 1] + f[L + 1][R] + a[L] * a[L + 1] * a[R]; for (int k = L + 2; k <= R - 1; k++) // 枚举区间内断点的【绝对】位置 f[L][R] = min(f[L][k] + f[k][R] + a[L] * a[k] * a[R], f[L][R]); } cout << f[1][n]; return 0; }
下面是
__int128
输入输出的一些写法。选你喜欢的背下来,熟练书写。更多写法请自行搜索,还要掌握__int128
能参与的运算,以及能在哪些场景和比赛中使用。ostream& operator << (ostream& out, LLL x) { if (!x) { out << 0; return out; } if (x < 0)x = -x; int stk[110], top = 0; while (x) { stk[++top] = x % 10; x /= 10; } for (int i = top; i >= 1; i--) out << stk[i]; return out; } void write(LLL x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10); putchar(x % 10 + '0'); } LLL read() { LLL x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') flag = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } return x * flag; }
- 1
Information
- ID
- 151
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 7
- Tags
- # Submissions
- 40
- Accepted
- 9
- Uploaded By