链接:点击打开链接
题意:在x轴上有n个客人,每个客人每秒增加的愤怒值不同。给出客人和餐厅的位置,以及客人每分钟增加的愤怒值,和送餐行走一公里需要的时间,问送完n个客人的外卖最小愤怒值
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
struct node{
int x,val;
friend bool operator<(node a,node b){
return a.x<b.x;
}
}s[1005];
int sum[1005],dp[1005][1005][2];
int main(){
int N,V,X,i,j,k,l;
while(scanf("%d%d%d",&N,&V,&X)!=EOF){
for(i=1;i<=N;i++) //dp[i][j][0]表示走完区间[i,j]停在左端点
scanf("%d%d",&s[i].x,&s[i].val); //dp[i][j][0]表示走完区间[i,j]停在右端点
s[N+1].x=X,s[N+1].val=0;
N++;
sort(s+1,s+N+1); //一定是先走相邻的点费用最小,因此先排序
memset(dp,INF,sizeof(dp));
sum[0]=0;
for(i=1;i<=N;i++){
sum[i]=sum[i-1]+s[i].val;
if(s[i].x==X&&s[i].val==0)
dp[i][i][0]=dp[i][i][1]=0;
} //将起点初始化
for(l=2;l<=N;l++){ //遍历四种可能,跟zoj3541有些相似
for(i=1;i<=N-l+1;i++){ //zoj3541:http://blog.csdn.net/stay_accept/article/details/51526272
j=i+l-1;
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(s[i+1].x-s[i].x)*(sum[i]+sum[N]-sum[j]));
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(s[j].x-s[i].x)*(sum[i]+sum[N]-sum[j]));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(s[j].x-s[i].x)*(sum[i-1]+sum[N]-sum[j-1]));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(s[j].x-s[j-1].x)*(sum[i-1]+sum[N]-sum[j-1]));
}
}
printf("%d\n",min(dp[1][N][0],dp[1][N][1])*V);
}
return 0;
}