题意: 给出一个数组, 每取走其中一个元素, 就要付出 它左边*它自己*它右边 的代价, 问要当取走除两头外所有的元素, 付出的最小代价是多少.
思路:
只需要dp[i][j]维护区间内都取完, 两头(i处和j处)还没取的最小代价即可.
在这样的情况下, 区间的最小长度当然是3.
然后当前区间枚举最后一个取走的元素, ①这个元素取走的代价+②③它左右两个区间早已取走的代价=当前区间的总代价.
dp[i][j]=min(②dp[i][k]+③dp[k][j]+①a[i]*a[j]*a[k]) (for k in i+1 to j-1)
代码:
//#include<bits/stdc++.h>
#include <cstdio>
#include <iostream>
using namespace std;
void debug_out() {
cerr << '\n';
}
template<typename T, typename ...R>
void debug_out(const T &f, const R &...r) {
cerr << f << " ";
debug_out(r...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__);
typedef long long ll;
const int M = 205;
const int inf = 1e9 + 5;
const int mod = 1e9 + 7;
int n;
int dp[M][M];
int a[M];
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (int len = 3; len <= n; len++) {
for (int s = 0; s < n; s++) {
int t = s + len - 1;
int tmp = inf;
for (int i = s+1; i < t; i++) {
tmp = min(dp[s][i] + dp[i][t] + a[s] * a[t] * a[i], tmp);
}
dp[s][t] = tmp;
}
}
/*
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d ", dp[i][j]);
}
puts("");
}
*/
printf("%d\n", dp[0][n - 1]);
return 0;
}