- 参考blog:
https://blog.csdn.net/sdjzping/article/details/19070869
- 题目:大意抄:
有一家快餐店送外卖,现在同时有n个家庭打进电话订购,送货员得以V-1的速度一家一家的运送,但是每一个家庭都有一个不开心的值,每分钟都会增加一倍,值达到一定程度,该家庭将不会再订购
外卖了,现在为了以后有更多的家庭订购,要将外卖送到的情况下使得所有用户的不开心值总和达到最小
很明显,每多走一分钟,没送到的家庭的不开心值都会加倍,
假设是这样的顺序123X456,从X出发先往左右中间靠近的送,再往两边送省时间
dp[i][j][0]表示从i到j用户送到最小不开心值,此时送货员停留在左边即i位置
dp[i][j][1]表示从i到j用户送到最小不开心值,此时送货员停留在右边即j位置
状态有四种,
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(a[i+1].x-a[i].x)*(delay+a[i].v));
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(a[j].x-a[i].x)*(delay+a[i].v));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(a[j].x-a[i].x)*(delay+a[j].v));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(a[j].x-a[j-1].x)*(delay+a[j].v));
-
本人思路:
一开始其实和上面的状态转移方程大致一样,就是漏了个delay,于是我以为每个dp除了记录总b还得记录时间,但是这并不需要。因为如果我们已经把还没到的家庭的产生的不开心值算进去,那么后面由此得到的母区间的状态就不需要时间去维护了。这是关键。 小错误: 一开始的dp初始化: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190731233815646.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzc2ODc3NA==,size_16,color_FFFFFF,t_70) 这个是有问题,因为没有把所有的dp都初始化了,那些还是会用到的比如dp[i][i]这种就完全初始化到。debug很久才发现这个问题。。
-
代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=1e3+4;
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const double pi=acos(-1.0);
struct node{
int b;int x;
node(int _x,int _b):x(_x),b(_b)
{
}
node(){}
bool operator<(const node & tmp)const{
return x<tmp.x;
}
bool operator == (const node & tmp)const{
return x==tmp.x;
}
}p[maxn];
LL sum[maxn];
LL dp[maxn][maxn][2];
int N,V,X;int x,b;
int main()
{
while(cin>>N>>V>>X)
{
memset(sum,0,sizeof(sum));
for(int j=1;j<=N;j++)
{
cin>>x>>b;
p[j]=node(x,b);
}
p[N+1].x=X;
p[N+1].b=0;
sort(p+1,p+N+2);
int pos;
pos=find(p+1,p+N+2,node(X,0))-p;
for(int j=1;j<=N+1;j++)
sum[j]=sum[j-1]+p[j].b;
for(int i=1; i<=N+1; i++)
{
for(int j=1; j<=N+1; j++)
dp[i][j][0]=dp[i][j][1]=INF;
}
dp[pos][pos][0]=dp[pos][pos][1]=0;
for(int i=pos;i>=1;i--)
{
for(int j=pos;j<=N+1;j++)
{
LL delay=sum[i-1]+sum[N+1]-sum[j];
if(i==j)
continue;
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(p[i+1].x-p[i].x)*(delay+p[i].b));
dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(p[j].x-p[i].x)*(delay+p[i].b));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(p[j].x-p[j-1].x)*(delay+p[j].b));
dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(p[j].x-p[i].x)*(delay+p[j].b));
}
}
cout<<min(dp[1][N+1][0],dp[1][N+1][1])*V<<endl;//注意这里先把V当作1,前面计算好操作,最后记得加V。
}
}