分析:
想了个dp。令
dp[i]
是最后一个冰淇淋站建在i的花费,那么有转移方程
dp[i]=min(dp[j]+val[i]−∑dis[i]−dis[j])
看了一下,好像还有 O(n) 的dp方法,我要再学习一下。
PS:感觉这一场可以和队友一起训练一下的,结果我自己智障,一个人就开题了= =
代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 3005;
long long dp[maxn];
long long sum[maxn];
struct Node {
long long x, c;
bool operator <(const Node &rhs) const {
return x < rhs.x;
}
}node[maxn];
int n;
int main(int argc, char const *argv[]) {
while (~scanf("%d", &n)) {
for (int i = 1; i <= n; i ++)
scanf("%lld%lld", &node[i].x, &node[i].c);
sort(node + 1, node + n + 1);
for (int i = 1; i <= n; i ++) {
sum[i] = node[i].x;
sum[i] += sum[i - 1];
}
for (int i = 1; i <= n; i ++) dp[i] = 1e18;
dp[1] = node[1].c + (sum[n] - sum[0]) - n * node[1].x;
for (int i = 2; i <= n; i ++)
for (int j = 1; j < i; j ++)
dp[i] = min(dp[i], dp[j] + node[i].c - (n - i + 1) * (node[i].x - node[j].x));
long long ans = 1e18;
for (int i = 1; i <= n; i ++)
ans = min(ans, dp[i]);
cout<<ans<<endl;
}
return 0;
}