zoukankan      html  css  js  c++  java
  • bzoj 1705;poj 3612:[Usaco2007 Nov]Telephone Wire 架设电话线

    Description

    最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线。 新的电话线架设在已有的N(2 <= N <= 100,000)根电话线杆上, 第i根电话线杆的高度为height_i米(1 <= height_i <= 100)。 电话线总是从一根电话线杆的顶端被引到相邻的那根的顶端 如果这两根电话线杆的高度不同,那么FJ就必须为此支付 C*电话线杆高度差(1 <= C <= 100)的费用。当然,你不能移动电话线杆, 只能按原有的顺序在相邻杆间架设电话线。Farmer John认为 加高某些电话线杆能减少架设电话线的总花费,尽管这项工作也需要支出一定的费用。 更准确地,如果他把一根电话线杆加高X米的话,他得为此付出X^2的费用。 请你帮Farmer John计算一下,如果合理地进行这两种工作,他最少要在这个电话线改造工程上花多少钱。

    Input

    * 第1行: 2个用空格隔开的整数:N和C

    * 第2..N+1行: 第i+1行仅有一个整数:height_i

    Output

    * 第1行: 输出Farmer John完成电话线改造工程所需要的最小花费

    Sample Input

    5 2
    2
    3
    5
    1
    4
    输入说明:
    一共有5根电话线杆,在杆间拉电话线的费用是每米高度差$2。
    在改造之前,电话线杆的高度依次为2,3,5,1,4米。


    Sample Output

    15
    输出说明:
    最好的改造方法是:Farmer John把第一根电话线杆加高1米,把第四根加高2米,
    使得它们的高度依次为3,3,5,3,4米。这样花在加高电线杆上的钱是$5。
    此时,拉电话线的费用为$2*(0+2+2+1) = $10,总花费为$15。

     
    说好的动态规划……其实最后还得用贪心优化……一个位置的最优策略完全可以分左右两边考虑,然后一边更新状态一边更新当前最优解就行了……可怜的单调性!
     
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    int n,c,h,le,f[2][101],i,j,xx;
    char cs;
    int read(){
        cs=getchar();xx=0;
        while(cs<'0'||cs>'9') cs=getchar();
        while(cs>='0'&&cs<='9') xx=xx*10+cs-48,cs=getchar();
        return xx;
    }
    int main(){
        n=read();c=read();h=read();
        for (i=1;i+h<=100;i++) f[0][i+h]=i*i;
        le=h;
        int la=1,now=0,mi,x;
        for (i=1;i<n;i++){
            swap(la,now);
            h=read();
            x=h;
            if (h<le){
                mi=f[la][le]+abs(le-h)*c;
                for (j=le+1;j<=100;j++)
                if (mi>f[la][j]+abs(j-h)*c) mi=f[la][j]+abs(j-h)*c;
                for (j=h;j<le;j++) f[now][j]=mi,mi-=c;
                h=le;
            }
            mi=f[la][le]+abs(le-h)*c;
            for (j=le;j<h;j++) if (mi>f[la][j]+abs(j-h)*c) mi=f[la][j]+abs(j-h)*c;
            for (;j<=100;j++){
                if (mi>f[la][j]) mi=f[la][j];
                f[now][j]=mi;
                mi+=c;
            }
            mi=f[la][100]+c;
            for (j=99;j>=h;j--){
                if (f[now][j]>mi) f[now][j]=mi;
                if (mi>f[la][j]) mi=f[la][j];
                mi+=c;
            }
            for (j=1;j+x<=100;j++) f[now][j+x]+=j*j;
            le=x;
        }
        h=f[now][le];
        for (i=le+1;i<=100;i++)
        if (f[now][i]<h) h=f[now][i];
        printf("%d
    ",h);
    }
  • 相关阅读:
    作业2 四则运算
    自动生成小学四则运算题目(加强版)
    Oracle 转移符问题
    《一个程序猿的生命周期》有感
    自问自答总结
    The Last Reader Response——13-17
    读《构建之法》十一、十二章有感
    《构建之法》8,9,10,章有感
    第二天冲刺(个人工作)
    冲刺第一天(个人工作)
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5049246.html
Copyright © 2011-2022 走看看