agc035D
題意
給定n個數字。每次選擇三個連續的位置,刪去中間的數,將中間的數的值加在左右的兩個數上。最小化剩下的兩個數的和。
題解
我們把刪數的過程反過來看做吐數的過程:最開始只有兩個數,其他的數字將會被填在他們兩個之間。最開始的兩個數對目標函數的貢獻都是1。
考慮我們現在剩下k張牌,他們對目標函數的貢獻分別是那麼如果我們在第個數和第 個數之間插入一個數,這個數對目標函數的貢獻要乘以。
那麼構思一個, 表示區間張卡片對目標函數的貢獻,那麼每次我們選擇區間中的一個數來作爲這個區間中第一被吐出來的數。
#include <bits/stdc++.h>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define dow(i,j,k) for (int i = j; i >= k; i--)
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
typedef pair<int, int> pi;
typedef long long ll;
int n;
ll a[20];
long long ans;
ll find(int l, int xl, int r, int xr) {
if (l + 1 == r) return 0;
long long res = 1e18;
for (int i = l + 1; i < r; i++)
res = min(res, find(l, xl, i, xl + xr) + find(i, xl + xr, r, xr) + a[i] * (xl + xr));
return res;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
cout << find(1, 1, n, 1) + a[1] + a[n] << endl;
}