题意:
给你n个球,一开始球都往左滚,使球停止有两种方法。
1.把它钉起来,给你一个花费。
2.让它滚到钉起来的球旁边。花费为距离。
让你求使所有球停止的最少花费。
POINT:
dp[i],代表钉下i这个球后(1-i)球的最少花费。
打表cost[i][j]数组代表,j+1到i这些球全部滚到j这个球上的距离。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 3333;
#define LL long long
struct node
{
LL x,cost;
friend bool operator < (node a,node b)
{
return a.x<b.x;
}
}a[3333];
LL cost[maxn][maxn];
LL dp[maxn];
int main()
{
LL n;
scanf("%lld",&n);
for(LL i=1;i<=n;i++){
scanf("%lld%lld",&a[i].x,&a[i].cost);
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
cost[j][i]=a[j].x-a[i].x;
}
for(int j=i+1;j<=n;j++){
cost[j][i]+=cost[j-1][i];
}
}
/*for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
printf("%lld ",cost[j][i]);
}
printf("\n");
}*/
dp[1]=a[1].cost;
for(int i=2;i<=n;i++){
dp[i]=13278126378612783;
for(int j=1;j<i;j++){
dp[i]=min(dp[i],dp[j]+cost[i-1][j]+a[i].cost);
}
}
LL Min=13278126378612783;
for(int i=1;i<=n;i++){
Min=min(dp[i]+cost[n][i],Min);
}
printf("%lld\n",Min);
return 0;
}