题意
一个人从X点出发给N个点送食物,速度为1/v,如果第xi个点的客人没有收到食物,那么他的不满意度将会增加bi每分钟。问不满意度最少为多少?
题解
很有趣的一道区间DP题,将出发点也放入点集中,排序,进行区间DP。
dp[i][j][0]代表该人在I处,I到J的所有客人都已配送完成时最少的不满意度。
dp[i][j][1]代表该人在J处,I到J的所有客人都已配送完成时最少的不满意度。
由此可以得到状态转移方程
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(nodes[i+1].x-nodes[i].x)*(lt[i]+rt[j+1]));
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(nodes[j].x-nodes[i].x)*(lt[i]+rt[j+1]));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(nodes[j].x-nodes[i].x)*(lt[i-1]+rt[j]));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(nodes[j].x-nodes[j-1].x)*(lt[i-1]+rt[j]));
代码
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<string>
#include<set>
#include<map>
#include<bitset>
#define UP(i,l,h) for(int i=l;i<h;i++)
#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)
#define W(a) while(a)
#define MEM(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
#define MAXN 1010
#define EPS 1e-10
#define MOD 100000000
using namespace std;
struct Node {
int x,b;
bool operator <(const Node b) const {
return x<b.x;
}
};
Node nodes[MAXN];
int dp[MAXN][MAXN][2];
int lt[MAXN],rt[MAXN];
int main() {
int n,v,x;
W(~scanf("%d%d%d",&n,&v,&x)) {
UP(i,0,n) {
scanf("%d%d",&nodes[i].x,&nodes[i].b);
}
nodes[n].x=x,nodes[n].b=0;
n++;
sort(nodes,nodes+n);
MEM(dp,INF);
int pos=0;
UP(i,0,n) {
if(nodes[i].x==x)
pos=i;
}
MEM(lt,0);
MEM(rt,0);
lt[0]=nodes[0].b;
UP(i,1,n) {
lt[i]=lt[i-1]+nodes[i].b;
}
rt[n-1]=nodes[n-1].b;
DOWN(i,n-1,0) {
rt[i]=rt[i+1]+nodes[i].b;
}
dp[pos][pos][0]=dp[pos][pos][1]=0;
UP(len,1,n) {
UP(i,0,n) {
int j=i+len;
if(j>=n) {
continue;
}
// cout<<i<<" "<<j<<endl;
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(nodes[i+1].x-nodes[i].x)*(lt[i]+rt[j+1]));
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(nodes[j].x-nodes[i].x)*(lt[i]+rt[j+1]));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(nodes[j].x-nodes[i].x)*(lt[i-1]+rt[j]));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(nodes[j].x-nodes[j-1].x)*(lt[i-1]+rt[j]));
}
}
// cout<<dp[0][n][0]*v<<" "<<dp[0][n][1]*v<<endl;
printf("%d\n",min(dp[0][n-1][0]*v,dp[0][n-1][1]*v));
}
}
/*
5 1 5
1 1
2 2
3 3
4 4
5 5
*/