ZOJ 3469 Food Delivery(区间DP)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4255

题意:n个人订餐。n个人位于一条线上,饭店也在这条线上。每个人有一个脾气值p。若第i分钟得到他预定的饭不满意度为p*i。送饭人的速度已知。求一种送饭顺序使得总不满意度最小。

思路:设f[i][j][0],f[i] [j][1]分别表示将[i,j]区间的送完,最后停在左边或右边的最小不满意度。那么我们在DPf[i][j][0]时可以从f[i+1][j]进行转 移。我们发现,我们需要记录f[i+1][j]取得最优值时需要的时间t[i+1][j],这样我们才知道i得到饭时的时间,此时我们发现就不满足最优子 结构了,我们记f[i+1][j]和t[i+1][j]为二元组(X,Y),若有两种情况(X,Y)=(10,5),(X,Y)=(5,10),那么我们 保存前者还是后者呢?按照题意,我们应该保存后者,因为后者的不满意度最小,但是时间大,转移到的f[i][j][0]不见得比(10,5)这组优。。。 那么应该怎么做的?我们发现,前面的时间每增加1,其实后面还没有遍历的人的所有人的时间就会增加1,其相应不满意度的增加也就能算出来,我们若把这个不 满意度也加到当前DP的子问题中,那么t就不需要保存,比如从f[i+1][j][1]向f[i][j][0]转移时我们只需要直接计算j走到i的时间, 而f[i+1][j][0]所用的时间对后面产生的影响我们已经加入f[i+1][j][0]了,这样就满足最优子结构了。。。

i64 f[N][N][2],v,x,S[N];
int n;

struct node
{
    i64 x,y;
};

node a[N];

int cmp(node a,node b)
{
    return a.x<b.x;
}

i64 Cost(int i,int j)
{
    if(i>j) return 0;
    return S[j]-S[i-1];
}

void up(i64 &x,i64 y)
{
    if(x>y) x=y;
}

int main()
{
    Rush(n)
    {
        RD(v,x);
        int i,j;
        FOR1(i,n) RD(a[i].x,a[i].y);
        a[++n].x=x; a[n].y=0;
        sort(a+1,a+n+1,cmp);
        int pos;
        FOR1(i,n) if(a[i].x==x) break;
        pos=i;
        FOR1(i,n) S[i]=S[i-1]+a[i].y;
        FOR1(i,n) FOR1(j,n) f[i][j][0]=f[i][j][1]=inf;
        f[pos][pos][0]=f[pos][pos][1]=0;
        i64 temp;
        for(i=pos;i>=1;i--) for(j=pos;j<=n;j++)
        {
            if(i==j) continue;
            temp=Cost(1,i-1)+Cost(j+1,n);
            up(f[i][j][0],f[i+1][j][0]+(temp+a[i].y)*(a[i+1].x-a[i].x));
            up(f[i][j][0],f[i+1][j][1]+(temp+a[i].y)*(a[j].x-a[i].x));
            up(f[i][j][1],f[i][j-1][0]+(temp+a[j].y)*(a[j].x-a[i].x));
            up(f[i][j][1],f[i][j-1][1]+(temp+a[j].y)*(a[j].x-a[j-1].x));
        }
        i64 ans=min(f[1][n][0],f[1][n][1]);
        ans*=v;
        PR(ans);
    }
}

ZOJ 3469 Food Delivery(区间DP),布布扣,bubuko.com

时间: 2024-12-19 22:42:06

ZOJ 3469 Food Delivery(区间DP)的相关文章

zoj 3469 Food Delivery 区间dp + 提前计算费用

Time Limit: 2 Seconds      Memory Limit: 65536 KB When we are focusing on solving problems, we usually prefer to stay in front of computers rather than go out for lunch. At this time, we may call for food delivery. Suppose there are N people living i

zoj 3469 Food Delivery(区间dp)

Food Delivery Time Limit: 2 Seconds      Memory Limit: 65536 KB When we are focusing on solving problems, we usually prefer to stay in front of computers rather than go out for lunch. At this time, we may call for food delivery. Suppose there are N p

ZOJ 3469 Food Delivery (区间DP,经典)

题意: 在x轴上有一家外卖餐馆,有n个顾客站在x轴上不同坐标上且叫了外卖,每个人的脾气不同,每1分钟没有收到外卖就会增加Fi点愤怒值,而外卖小哥的车是有速度的v-1/分钟,问怎样的送餐次序会让所有顾客的愤怒值之和最小?输出愤怒值之和! 思路: 此题是很经典了,比较现实的模型. 随便画画就知道小哥可以一下子往左一下子往右走,往返多次也是有可能的,取决于顾客的愤怒系数Fi.那么在考虑一个区间[L,R]时,其任一子区间都必须是已经被考虑过了.现在考虑区间[L,R]可以转移到哪里,明显可以分别转移到[L

ZOJ - 3469 —— Food Delivery

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3469 dp[i][j][0] := 派送区间[i,j]的用户并且最后派送 i 时的最小值 dp[i][j][1] := 派送区间[i,j]的用户并且最后派送 j 时的最小值 dp[i][j][0] = min(dp[i+1][j][0]+cost1, dp[i+1][j][1]+cost2) dp[i][j][1] = min(dp[i][j-1][0]+cost3

ZOJ3469 Food Delivery[区间dp]

Food Delivery Time Limit: 2 Seconds      Memory Limit: 65536 KB When we are focusing on solving problems, we usually prefer to stay in front of computers rather than go out for lunch. At this time, we may call for food delivery. Suppose there are N p

ZOJ 3469 Food Delivery

 Food Delivery Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description When we are focusing on solving problems, we usually prefer to stay in front of computers rather than go out for lunch. At this time, we may call fo

ZOJ - 3537 Cake (凸包+区间DP+最优三角剖分)

Description You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for the invited comers. You have a knife to cut. The trace of each cut is a line segment, whose two endpoin

ZOJ 3537 Cake (区间DP,三角形剖分)

题意: 给出平面直角坐标系上的n个点的坐标,表示一个多边形蛋糕,先判断是否是凸多边形,若否,输出"I can't cut.".若是,则对这个蛋糕进行3角形剖分,切n-3次变成n-2份三角形蛋糕给小伙伴吃,但是每切一次需要一个费用,公式是:cost[i][j] = |xi + xj| * |yi + yj| % p 表示在两点i和j之间切一刀的费用.问最少费用是多少? 思路: 判断是否凸多边形需要用到求凸包的Andrew算法,时间复杂度为O(nlogn),然后判断凸包内的点数是否为n就行

Food Delivery ZOJ - 3469 (区间dp)

Food Delivery ZOJ - 3469 题意:快递员送外卖,n个客户,起始位置为x,速度为v,每个客户单位时间不满意度增加hi,问最少增加多少不满意度. 每一个客户可能是从左侧送到或者从右侧送到. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define CLR(m,a) memset(m,a,sizeof(m)) 4 const int maxn=1010; 5 const int inf=0x3f3f3f3f; 6 i