思路:
说是简单dp。。。
其实有点乱
#include <cstdio>
#include <iostream>
#include <string.h>
#include <queue>
#include <algorithm>
typedef long long int lli;
using namespace std;
struct node{
int p,v;
}a[3030];
bool cmp(const node&a,const node&b){
return a.p<b.p;
}
lli dp[3030][3030];// i是第几个商店 j是i左边的最右边的商店的标号
int main(){
int n;
while(~scanf("%d",&n)){
memset(dp,0,sizeof(dp));
for(int i = 1;i <= n;i++){
scanf("%d%d",&a[i].p,&a[i].v);
}
sort(a+1,a+1+n,cmp);//注意排序 否则会wa
dp[1][1] = a[1].v;
lli temp;
for(int i = 2;i <= n;i++){
temp = dp[i-1][1];
for(int j = 1;j < i;j++){
dp[i][j] = dp[i-1][j] + a[i].p-a[j].p;
temp = min(temp,dp[i-1][j]); //找出前一个商店选择好之后花费最少的一个状态
}
dp[i][i] = temp + a[i].v;
}
lli ans = 0x3f3f3f3f;
for(int i = 1;i <= n;i++){
ans = min(ans,dp[n][i]);
}
printf("%lld\n",ans);
}
}
改进:
发现可以进一步优化空间,因为我们每次只用了上一层的数据。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <queue>
#include <algorithm>
typedef long long int lli;
using namespace std;
struct node{
int p,v;
}a[3030];
bool cmp(const node&a,const node&b){
return a.p<b.p;
}
lli dp[3030];
int main(){
int n;
while(~scanf("%d",&n)){
memset(dp,0,sizeof(dp));
for(int i = 1;i <= n;i++){
scanf("%d%d",&a[i].p,&a[i].v);
}
sort(a+1,a+1+n,cmp);
dp[1] = a[1].v;
for(int i = 2;i <= n;i++){
lli mmin = 0x3f3f3f3f;
for(int j = 1;j < i;j++){
mmin = min(mmin,dp[j]);
dp[j] += a[i].p-a[j].p;
}
dp[i] = mmin + a[i].v;
}
lli ans = dp[1];
for(int i = 2;i <= n;i++){
ans = min(ans,dp[i]);
}
printf("%lld\n",ans);
}
}