agc035d

AGC035D是一道数学题目,要求通过逆向思考删除连续三个数字的操作,转化为添加数字的过程,从而最小化剩余两个数字的和。解题策略涉及动态规划,考虑在不同区间内选择一个数字作为首次添加的数字,以求最优解。

agc035D

题意

​ 给定n个数字。每次选择三个连续的位置,删去中间的数,将中间的数的值加在左右的两个数上。最小化剩下的两个数的和。

题解

​ 我们把删数的过程反过来看做吐数的过程:最开始只有两个数,其他的数字将会被填在他们两个之间。最开始的两个数对目标函数的贡献都是1。

​ 考虑我们现在剩下k张牌,他们对目标函数的贡献分别是x1,...,xkx_1, ... , x_kx1,...,xk那么如果我们在第iii个数和第i+1i + 1i+1 个数之间插入一个数,这个数对目标函数的贡献要乘以xi+xi+1x_i +x_{i+1}xi+xi+1

​ 那么构思一个dpdpdp, dp([l][xl][r][xr])dp([l][x_l][r][x_r])dp([l][xl][r][xr])表示区间第l到第r第l到第rlr张卡片对目标函数的贡献,那么每次我们选择区间中的一个数来作为这个区间中第一被吐出来的数。dp[l][xl][r][xr]=minl<m<rdp[l][xl][m][xl+xr]+dp[m][xl+xr][r][xr]+a[m]∗(xl+xr)dp[l][x_l][r][x_r] = min_{l<m<r}dp[l][x_l][m][x_l +x_r] + dp[m][x_l + x_r][r][x_r] +a[m] * (x_l +x_r)dp[l][xl][r][xr]=minl<m<rdp[l][xl][m][xl+xr]+dp[m][xl+xr][r][xr]+a[m](xl+xr)

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值