zoukankan      html  css  js  c++  java
  • ZOJ 3469 Food Delivery(区间DP)

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

    DP的思路就是,如果要访问完[i,j],那么它的子区间一定访问完了。

    用dp[i][j][0]表示访问完区间[i,j]并留在左端点,dp[i][j][1]表示访问完区间[i,j]并留在右端点。

    把饭店那个地方也加进去作为点。从饭店那个点往两边进行DP;

    dp[i][j][0]  可以根据dp[i+1][j][0]和dp[i+1][j][1]得到。

    dp[i][j][1] 可以根据dp[i][j-1][0]和dp[i][j-1][1]得到。

    //============================================================================
    // Name        : ZOJ.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const int MAXN=1010;
    const int INF=0x3f3f3f3f;
    struct Node
    {
        int x,b;
    };
    Node node[MAXN];
    int dp[MAXN][MAXN][2];
    bool cmp(Node a,Node b)
    {
        return a.x<b.x;
    }
    int sum[MAXN];
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        int n,v,x;
        while(scanf("%d%d%d",&n,&v,&x)==3)
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&node[i].x,&node[i].b);
            }
            n++;
            node[n].x=x;
            node[n].b=0;
            sort(node+1,node+n+1,cmp);
            sum[0]=0;
            for(int i=1;i<=n;i++)
                sum[i]=sum[i-1]+node[i].b;
            int tmp;
            for(int i=1;i<=n;i++)
                if(node[i].x==x)
                {
                    tmp=i;
                    break;
                }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    dp[i][j][0]=dp[i][j][1]=INF;
            dp[tmp][tmp][0]=dp[tmp][tmp][1]=0;
            for(int i=tmp;i>=1;i--)
                for(int j=tmp;j<=n;j++)
                {
                    if(i==j)continue;
                    dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(sum[i]+sum[n]-sum[j])*(node[i+1].x-node[i].x));
                    dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(sum[i]+sum[n]-sum[j])*(node[j].x-node[i].x));
    
                    dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(sum[i-1]+sum[n]-sum[j-1])*(node[j].x-node[i].x));
                    dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(sum[i-1]+sum[n]-sum[j-1])*(node[j].x-node[j-1].x));
                }
            printf("%d\n",v*min(dp[1][n][0],dp[1][n][1]));//本题的v一定要留到后面来乘,中间DP的时候乘可能会溢出,导致WA
        }
        return 0;
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    ECMAScript 6学习笔记(二):let和块级作用域
    ECMAScript 6学习笔记(一):展开运算符
    JavaScript的作用域和闭包
    HTML中行内元素的竖直方向的padding和margin是否真的无效
    <input type="text"/>未输入时属性value的默认值--js学习之路
    Matlab 之 FFT的理解和应用
    .NET 5.0实现Consul服务注册
    面向对象编程思想(OOP)
    又再回归一次
    阿里云的OCS缓存机制
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3051919.html
Copyright © 2011-2022 走看看