ZOJ 3469 Food Delivery
题目大意:
有n个人,住在一条直线上。第i个人的坐标是Xi,街上有个外卖餐馆的位置是X,现在餐厅工作人员要给街上的每个人送饭,送完之后再回到餐厅,送饭人的速度是V,每个人有个不满意值,当这个人送餐时间每晚一分钟,则这个人的不满意值增加Bi. 要求总的不满意值最小。
===============================================================================================================
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL INF = 1e9+7; const LL maxn = 1e3+5; const LL MOD = 1e9+7; int dp[2][maxn][maxn], sum[maxn]; struct node { int X, B; bool friend operator < (node A, node B) { return A.X < B.X; } } P[maxn]; int main() { int n, v, x; while(cin >> n >> v >> x) { for(int i=1; i<=n; i++) cin >> P[i].X >> P[i].B; P[n+1].X = x, P[n+1].B = 0; n ++; memset(dp, 0, sizeof(dp)); memset(sum, 0, sizeof(sum)); sort(P+1, P+1+n); sum[0] = 0; for(int i=1; i<=n; i++) sum[i] = sum[i-1] + P[i].B; int Star; for(int i=0; i<=n+1; i++) for(int j=0; j<=n+1; j++) dp[0][i][j] = dp[1][i][j] = INF; for(int i=1; i<=n; i++) { if(P[i].X == x) { Star = i; break; } } dp[0][Star][Star] = dp[1][Star][Star] = 0; for(int i=Star; i>=1; i--) for(int j=Star; j<=n; j++) { dp[0][i][j] = min(dp[0][i][j], dp[0][i+1][j] + (P[i+1].X - P[i].X)*(sum[n]-sum[j]+sum[i]) ); dp[0][i][j] = min(dp[0][i][j], dp[1][i+1][j] + (P[j].X - P[i].X)*(sum[n]-sum[j]+sum[i]) ) ; dp[1][i][j] = min(dp[1][i][j], dp[0][i][j-1] + (P[j].X - P[i].X)*(sum[n]-sum[j-1]+sum[i-1]) ); dp[1][i][j] = min(dp[1][i][j], dp[1][i][j-1] + (P[j].X - P[j-1].X)*(sum[n] - sum[j-1] + sum[i-1]) ); } printf("%d\n", min(dp[0][1][n],dp[1][1][n])*v); } return 0; }