zoukankan      html  css  js  c++  java
  • Food Delivery

    题目链接:https://vjudge.net/problem/ZOJ-3469#author=SCUACM2020

    题意:你要给n个顾客送外卖,第i个顾客在a[i].x位置,且每过1min第i个顾客就会增加a[i].v的怒气。你的初始位置在p点,且你走1米所用的时间是m分钟。问你送完所有的外卖,顾客的怒气值之和最小是多少。

    思路:区间dp,出发先往左右中间靠近的送,再往两边送省时间。设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)*(s+a[i].v));
                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(a[j].x-a[i].x)*(s+a[i].v));
                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(a[j].x-a[i].x)*(s+a[j].v));
                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(a[j].x-a[j-1].x)*(s+a[j].v));

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define INF 0x7ffffff
    const int maxn = 1005;
    const int mod = 1000000007;
    int dp[maxn][maxn][2];
    int sum[maxn];
    int n,m,p;
    struct node
    {
        int x,v;
    } a[maxn];
    bool cmp(node x,node y)
    {
        return x.x<y.x;
    }
    void DP()
    {
        int res;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
                dp[i][j][0]=dp[i][j][1]=INF;
        }
        for(int i=1; i<=n; i++)
        {
            if(a[i].x==p)
            {
                res=i;
                break;
            }
        }
        dp[res][res][0]=dp[res][res][1]=0;
        for(int i=res; i>=1; i--)
        {
            for(int j=res; j<=n; j++)
            {
                int s=sum[i-1]+sum[n]-sum[j];
                if(i==j)
                    continue;
                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(a[i+1].x-a[i].x)*(s+a[i].v));
                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(a[j].x-a[i].x)*(s+a[i].v));
                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(a[j].x-a[i].x)*(s+a[j].v));
                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(a[j].x-a[j-1].x)*(s+a[j].v));
            }
        }
    }
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&p))
        {
            for(int i=1; i<=n; i++)
                cin>>a[i].x>>a[i].v;
            n++;
            a[n].x=p;
            a[n].v=0;
            sort(a+1,a+n+1,cmp);
            for(int i=1; i<=n; i++)
                sum[i]=sum[i-1]+a[i].v;
            DP();
            cout<<min(dp[1][n][0],dp[1][n][1])*m<<endl;
        }
    }
  • 相关阅读:
    android中样式和自定义button样式
    android——实现多语言支持
    sizeof,数组,指针
    C++预处理相关
    内联函数
    牛客C++刷题
    leetcode刷题列表
    ends在linux和Windows下输出结果不同
    计算机负数为什么使用补码及浮点型计算
    个人技术博客:VUE:0基础入门
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/13681760.html
Copyright © 2011-2022 走看看