• ZOJ 3469 Food Delivery(* 区间DP 总结)





    题意:

    有一家快餐店送外卖,现在同时有n个家庭打进电话订购,送货员得以V-1的速度一家一家的运送,但是每一个家庭都有一个不开心的值,每分钟都会增加一倍,值达到一定程度,该家庭将不会再订购外卖了,现在为了以后有更多的家庭订购,要将外卖送到的情况下使得所有用户的不开心值总和达到最小

    很明显,每多走一分钟,没送到的家庭的不开心值都会加倍,

    假设是这样的顺序123X456,从X出发先往左右中间靠近的送,再往两边送省时间



    其实现在看来DP的不少问题开始的时候都可以使用贪心或者是搜索的思想来考虑的,因为很多时候可能用不到DP,贪心和搜索就够了,这也是人正常的思维过程吧算是。如果 复杂度太大(搜索方法),或者是不符合逻辑(贪心方法)的话,这样可能就需要用记忆化搜索或者是DP来解决时间复杂度和逻辑最优问题了(废话有点多!!!)

    (1)分析最优子结构(子结构分析) 对于restaurant的位置来说,可以先向左走k个位置,也就是先完成他左边的k个送餐任务,当然也可以向右走k个位置,也就是先完成右边的m个任务,因此这样的话就可以把整体任务进行划分了,先把小区间做出来,然后合并到当前位置就好了
    (2)确定dp状态的含义

    dp[i][j][0]表示从i到j用户送到最小不开心值,此时送货员停留在左边即i位置

    dp[i][j][1]表示从i到j用户送到最小不开心值,此时送货员停留在右边即j位置


    (3)得到递推方程式

                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)    );

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1005
    #define INF 0x7ffffff
    int dp[N][N][2];///从i到j用户送到最小不开心值,此时送货员停留在左(右)边即i(j)位置
    int n,V,X;
    int sum[N];    //前i个不满意度和
    struct node
    {
        int loc;
        int idx;
    }a[N];
    int cmp(node b,node c)
    {
        return b.loc<c.loc;
    }
    
    int Delay(int l,int r)
    {
        if(l>r)  return 0;
        return sum[r]-sum[l-1];
    }
    void solve()
    {
        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].loc==X)
            {
                res=i;
                break;
            }
    
        dp[res][res][0]=dp[res][res][1]=0;
        for(int i=res; i>=1; i--)     ///i循环restaurant左边的
            for(int j=res; j<=n; j++) ///j循环restaurant右边的
            {
                int delay=Delay(1,i-1)+Delay(j+1,n);
                if(i==j)   continue;
                dp[i][j][0]=min(  dp[i][j][0],  dp[i+1][j][0]+(a[i+1].loc-a[i].loc)*(delay+a[i].idx)  );
                dp[i][j][0]=min(  dp[i][j][0],  dp[i+1][j][1]+(a[j].loc-a[i].loc)*(delay+a[i].idx)    );
                dp[i][j][1]=min(  dp[i][j][1],  dp[i][j-1][0]+(a[j].loc-a[i].loc)*(delay+a[j].idx)    );
                dp[i][j][1]=min(  dp[i][j][1],  dp[i][j-1][1]+(a[j].loc-a[j-1].loc)*(delay+a[j].idx)  );
            }
    }
    
    int main()
    {
        while(scanf("%d%d%d",&n,&V,&X)!=EOF)
        {
            for(int i=1; i<=n; i++)
                scanf("%d%d",&a[i].loc,&a[i].idx);
    
            a[n+1].loc=X,a[n+1].idx=0;
            n++;
            sort(a+1,a+n+1,cmp);
            memset(sum,0,sizeof(sum));
            for(int i=1; i<=n; i++)
                sum[i]=sum[i-1]+a[i].idx;
                
            solve();
            printf("%d
    ",min(dp[1][n][0],dp[1][n][1])*V);
        }
        return 0;
    }
    



  • 相关阅读:
    第13组_16通信3班_045_OSPFv3作业
    RIPng配置(第十三组)
    基于IPV6的数据包分析(更新拓扑加入了linux主机和抓取133icmp包)(第十三组)
    vmware vsphere powercli 因为在此系统中禁止执行脚本
    vmware virtual machine must be running in order to be migrated
    flashback transaction闪回事务查询
    oracle 闪回功能详解
    linux下修改/dev/shm tmpfs文件系统大小
    vmware虚拟机guest系统重启后获得169.254.X.X的ip解决方法
    一键部署 PPTP server
  • 原文地址:https://www.cnblogs.com/zswbky/p/6792881.html
Copyright © 2020-2023  润新知