CF38E 题解

思路

首先按照位置从小到大排序。

dpi,jdp_{i,j} 表示对于前 ii 个弹珠,最后一个停止的弹珠。当 j<ij<i 时,那么 ii 号弹珠要滚到 jj 号弹珠的位置,耗费 xixjx_i-x_jdpi,j=dpi1,j+xixjdp_{i,j}=dp_{i-1,j}+x_i-x_j;当 j=ij=i 时,则直接把它停住,dpi,j=(mink=1i1dpi1,k)+Cidp_{i,j}=(\min\limits_{k=1}^{i-1}dp_{i-1,k})+C_i

代码

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
const ll inf = 1e18;
int n, tot;
ll dp[3005][3005], minx = inf;
pll a[3005];
bool cmp (const pll& a, const pll& b) {
	return a.first != b.first ? a.first < b.first : a.second < b.second;
}
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> n;
	for (int i = 0; i < n; ++ i)
		cin >> a[i].first >> a[i].second;
	sort (a, a + n, cmp);
	dp[0][0] = a[0].second;
	for (int i = 1; i < n; ++ i) {
		dp[i][i] = inf;
		for (int j = 0; j < i; ++ j)
			dp[i][j] = dp[i - 1][j] + a[i].first - a[j].first, dp[i][i] = min (dp[i][i], dp[i - 1][j]);
		dp[i][i] += a[i].second;
	}
	for (int i = 0; i < n; ++ i)
		minx = min (minx, dp[n - 1][i]);
	cout << minx;
	return 0;
}
posted @ 2024-05-15 14:57  Vitamin_B  阅读(10)  评论(0)    收藏  举报  来源