zoukankan      html  css  js  c++  java
  • P2885 [USACO07NOV]电话线Telephone Wire

    P2885 [USACO07NOV]电话线Telephone Wire

    最近,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计算一下,如果合理地进行这两种工作,他最少要在这个电话线改造工程上花多少钱。

    Solution

    设计dp状态为 (dp[i][j]) 表示考虑前 (i) 个柱子, 并且将第 (i) 个柱子的高度改造为 (j) 的最小花费
    容易想出 (dp) 方程: $$dp[i][j] = min(dp[i - 1][k] + (j - h[i])^{2} + |j - k| * c)$$
    复杂度 (O(nC_{2}))
    考虑优化
    发现绝对值比较难处理
    我们先把无关 (k) 的值提出来, 分类讨论处理一下绝对值

    [dp[i][j] = min(dp[i - 1][k] - c * k) + (j - h[i])^{2} + c * j (j geq k) ]

    [dp[i][j] = min(dp[i - 1][k] + c * k) + (j - h[i])^{2} - c * j (j leq k) ]

    然后 (min) 里可以用一个变量维护
    处理绝对值分别正序倒叙枚举即可

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(LL i = (x);i <= (y);i++)
    using namespace std;
    LL RD(){
        LL out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const LL maxn = 200019, inf = 0xfffffffffffffff;
    LL num, c, h[maxn];
    LL dp[maxn][119];
    LL maxx;
    void init(){
    	num = RD(), c = RD();
    	REP(i, 1, num)h[i] = RD(), maxx = max(maxx, h[i]);
    	REP(i, 0, num)REP(j, 0, maxx)dp[i][j] = inf;
    	}
    void solve(){
    	REP(i, h[1], maxx)dp[1][i] = (h[1] - i) * (h[1] - i);
    	REP(i, 2, num){
    		LL minn = inf;
    		REP(j, h[i - 1], maxx){
    			minn = min(minn, dp[i - 1][j] - j * c);
    			if(j < h[i])continue;
    			LL add = (j - h[i]) * (j - h[i]);
    			dp[i][j] = min(dp[i][j], minn + add + j * c);
    			}
    		minn = inf;
    		for(int j = maxx;j >= h[i];j--){
    			minn = min(minn, dp[i - 1][j] + j * c);
    			LL add = (j - h[i]) * (j - h[i]);
    			dp[i][j] = min(dp[i][j], minn + add - j * c);
    			}
    		}
    	LL ans = inf;
    	REP(i, h[num], maxx)ans = min(ans, dp[num][i]);
    	printf("%lld
    ", ans);
    	}
    int main(){
    	init();
    	solve();
    	return 0;
    	}
    
  • 相关阅读:
    广大数据结构复习之顺序表
    vs2017编译器编写c语言代码函数安全问题
    大数据学习之Spark Streaming进阶 52
    大数据学习之Spark Streaming基础 52
    大数据学习之SparkSQL数据源 51
    本地eclipse idea 写的Hadoop的API和 spark程序不能访问云服务器中的数据
    大数据学习之SparkSQL 50
    【PHP】上传图片翻转问题
    【Linux】CentOS7 安装gdb
    【Linux】yum [Errno 14] HTTP Error 404
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9921862.html
Copyright © 2011-2022 走看看