Description
有一个长度为n的序列,现取出其中除了最左和最右的元素(顺序任意),取出一个元素的代价为它本身乘相邻元素的乘积,现在想要以最小的代价取出这些元素。
Input
第一行输入一个n,代表元素的数量(n <= 100)第二行输入n个数 (a[i] <= 100);
Output
输出最小代价
Sample Input 1
6 10 1 50 50 20 5
Sample Output 1
3650
题解:
首先第一层循环枚举长度,dp[i][j]表示把i,j取出需要的最小代价,然后枚举最后i,j之间最后取的数。
#include <bits/stdc++.h>
using namespace std;
const long long INF = 1LL << 59;
int main()
{
ios::sync_with_stdio(false), cin.tie(0);
int n;
while(cin >> n) {
vector<long long> a (n + 2);
vector< vector<long long> > dp (n + 1, vector<long long> (n + 1, INF));
for(int i = 1; i <= n; ++i) cin >> a[i];
for(int i = 1; i <= n; ++i) {
if(i == 1 || i == n) dp[i][i] = dp[i][i] = 0;
else dp[i][i] = a[i - 1] * a[i + 1] * a[i];
}
for(int i = 1; i <= n; i ++) {
for(int j = i - 1; j >= 1; -- j) {
dp[i][j] = 0;
}
}
for(int d = 2; d < n; ++d) {
for(int st = 2; st + d - 1 < n; ++st) {
int ed = st + d - 1;
for(int k = st; k <= ed; ++k) {
dp[st][ed] = min(dp[st][ed], dp[st][k - 1] + dp[k + 1][ed] + a[k] * a[st - 1] * a[ed + 1]);
}
}
}
cout << dp[2][n-1] << '\n';
}
return 0;
}