zoukankan      html  css  js  c++  java
  • 【Uva 1336】Fixing the Great Wall

    Link:

    Description

    给你长城上的n个修补点,然后你的位置为x;
    你需要依次去这n个点,然后把它们全部修好.
    但是修的前后顺序不一样的话,花费不一样.
    如果立即把第i个点修好的话,需要c[i]点花费;
    每多t秒钟,就要多花费t*d[i]点花费.
    你一开始的位置在x,然后你的移动速度为v;
    修完所有的点的最小花费.

    Solution

    区间动态规划
    在任意时刻,你当前的位置,和你之前走的位置肯定是在连续的一段区间上的,因为你不可能跳过一个点不修,而去修它旁边的一个点.因为修的时候不用花费时间,是立刻就修好的!
    这样;
    设f[i][j][p]表示i..j这段区间全都走完了,现在在i..j这段区间的p端的最小花费,p=0表示左边,否则右边;
    把那个初始位置X放到n+1的位置;
    然后n++
    再把1..n按照x升序排序;
    从X的位置开始进行DP;
    X的位置是第i个;
    则从状态f[i][i][0]开始进行DP;
    因为这个状态不能知道走了多长的时间;
    所以可以用颜色长度这道题的思路,在进行一步扩展的时候;
    比如从i到了i-1;
    则t = (x[i]-x[i-1])/v;
    把1..i-1和i+1..n这些点的d[i]值的和乘上t加到答案里面去;
    (因为那些点的d值肯定是要乘上这个t值的);
    下次遇到那些点的时候,就只加上c值就可以了;
    这个f值要用double存,不能用整形;
    最后输出的时候
    用floor输出.

    NumberOf WA

    3

    Reviw

    这类题,因为修理的时间不计,所以最后肯定是形成一段段的区间.

    Code

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int N = 1000;
    const ll INF = 1e9+10;
    
    struct abc{
        double x,c,d;
    };
    
    int n;
    double v,X;
    double f[N+10][N+10][2],sum[N+10];
    abc a[N+100];
    
    int cmp(abc a,abc b){
        return a.x < b.x;
    }
    
    double get_sum(int x,int y){
        if (x>y) return 0;
        return sum[y]-sum[x-1];
    }
    
    double dfs(int l,int r,int p){
        if (f[l][r][p]>0){
            return f[l][r][p];
        }
        if (l==1 && r==n) return 0;
        double t1,t2,temp1 = -1,temp2 = -1;
        if (p==0){
            if (l-1>=1){
                t1 = (a[l].x-a[l-1].x)/v;
                temp1 = dfs(l-1,r,0) + a[l-1].c + get_sum(1,l-1)*t1
                    + get_sum(r+1,n)*t1;
            }
            if (r+1<=n){
                t2 = (a[r+1].x-a[l].x)/v;
                temp2 = dfs(l,r+1,1) + a[r+1].c + get_sum(1,l-1)*t2
                    + get_sum(r+1,n)*t2;
            }
        }else{//p==1
            if (l-1>=1){
                t1 = (a[r].x-a[l-1].x)/v;
                temp1 = dfs(l-1,r,0) + a[l-1].c + get_sum(1,l-1)*t1
                    + get_sum(r+1,n)*t1;
            }
            if (r+1<=n){
                t2 = (a[r+1].x-a[r].x)/v;
                temp2 = dfs(l,r+1,1) + a[r+1].c + get_sum(1,l-1)*t2
                    + get_sum(r+1,n)*t2;
            }
        }
        double &key = f[l][r][p];
        if (temp1<0) return key = temp2;
        if (temp2<0) return key = temp1;
        return key = min(temp1,temp2);
    }
    
    int main(){
        //freopen("F:\rush.txt","r",stdin);
        while (~scanf("%d%lf%lf",&n,&v,&X)){
            if (n==0) break;
            for (int i = 1;i <= n;i++)
                scanf("%lf%lf%lf",&a[i].x,&a[i].c,&a[i].d);
            a[n+1].x=X,a[n+1].c = 0,a[n+1].d = 0;
            n++;
            sort(a+1,a+1+n,cmp);
            sum[0] = 0;
            for (int i = 1;i <= n;i++)
                sum[i] = sum[i-1] + a[i].d;
    
            for (int i = 1;i <= n;i++)
                for (int j = 1;j <= n;j++)
                    f[i][j][0] = f[i][j][1] = -1;
    
            for (int i = 1;i <= n;i++)
                if (a[i].d==0){
                    printf("%.0f
    ",floor(dfs(i,i,0)));
                    break;
                }
        }
        return 0;
    }
    
  • 相关阅读:
    ubuntu14.04下安装node.js
    用U盘制作启动盘后空间变小的恢复方法,清除U盘启动盘空间
    JQuery入门——进度条
    setTimeout()与setInterval()——走马灯效果
    JavaScript日期控件,用select实现
    JavaScript获取元素CSS属性
    JavaScript为select添加option,select选项变化时的处理,获取slelect被选中的值
    Javascript为元素添加事件处理函数
    Javascript字数统计
    Struts2文件上传,以及各种注意事项
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626180.html
Copyright © 2011-2022 走看看