#include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<vector> #include<string.h> #include<map> #include<cmath> #include<queue> #include<stack> #define ll long long #define INF 0x7fffffff #define MAX 0x3f3f3f3f #define maxn 100005 #define ull unsigned long long using namespace std; struct node{ ll l;//坐标位置 ll c;//对应花费 }Node[3005]; ll dp[3005][2];//建或不建的花费 ll dis[3005][3005];//标记教学楼之间的距离 int n; bool cmp(node a,node b)//按坐标顺序 { return a.l<b.l; } int main() { ios::sync_with_stdio(false); int i,j; while(cin>>n) { for(i=1;i<=n;i++) cin>>Node[i].l>>Node[i].c; sort(Node+1,Node+n+1,cmp);//因为坐标不一定是按顺序输入 for(i=1;i<=n;i++) { dis[i][i]=0;//距自己距离为0 初始化 dp[i][0]=MAX;dp[i][1]=MAX;//第几个教室建和不建的花费 初始化 for(j=i+1;j<=n;j++)//枚举第i个教室之后的教室!!!!!!!!! dis[i][j]=dis[i][j-1]+Node[j].l-Node[i].l;//之前所有的j距i的距离,相当于叠加 } //dp[1][0]=MAX;第一个位置不建的花费设为很大值,根本不会不建 dp[1][1]=Node[1].c;//第一个位置建的花费 for(i=2;i<=n;i++)//下标从2开始!!!!!!!!! { dp[i][1]=min(dp[i-1][1],dp[i-1][0])+Node[i].c;//建的话,选上一个位置建或不建的花费里较小的那条路 for(j=i-1;j>=1;j--)//倒着枚举i之前的位置若建的花费!!!!! dp[i][0]=min(dp[i][0],dp[j][1]+dis[j][i]);//不建的话,取之前位置建的花费里最小值 } cout<<min(dp[n][0],dp[n][1])<<endl;//n位置建或不建的最小值 } return 0; }