• [USACO07NOV]电话线Telephone Wire


    题目描述

    电信公司要更换某个城市的网线。新网线架设在原有的 N(2 <= N <= 100,000)根电线杆上, 第
    i 根电线杆的高度为 height_i 米(1 <= height_i <= 100)。 网线总是从一根电线杆的顶端被引到
    相邻的那根的顶端,如果这两根电线杆的高度不同,那么电信公司就必须为此支付 C*电线
    杆高度差(1 <= C <= 100)的费用。电线杆不能移动, 只能在相邻电线杆间按原有的顺序架设
    网线。加高某些电线杆能减少架设网线的总花费,但需要支付一定的费用,一根电线杆加高
    X 米的费用是 X^2。 请你计算一下,如何合理地进行这两种工作,使网线改造工程的最小费
    用。

    输入

    • Line 1: Two space-separated integers: N and C

    • Lines 2..N+1: Line i+1 contains a single integer: heighti

    输出

    • Line 1: The minimum total amount of money that it will cost Farmer John to attach the new telephone wire. 

    样例输入

    5 2 2 3 5 1 4

    样例输出

    15

    f[i][j]表示前i根电线杆第i根高度为j是的最小费用

    f[i][j]=min(f[i-1][k]+c*abs(k-j))+(j-h[i])^2

    决策单调性:假设f[i][j-1]在k1时取最优,f[i][j]在k2时取最优,k2>=k1

    可用go变量记录f[i][j-1]取最优值的位置,计算f[i][j]时从go开始枚举 

     

    令函数p(k)=(f[i-1][k]+c*abs(k-j))

    p(k)是一个凹函数(随着k递增,p(k)先下降,后迅速上升)或者是单调递增函数 

    当p(k+1)>p(k)时,直接break,后面不存在更优的解 

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int n,c,maxh,h[100001],f[100001][101],go;
     7 int main()
     8 {int i,j,l;
     9 //freopen("file.in","r",stdin);
    10     cin>>n>>c;
    11      for (i=1;i<=n;i++)
    12      {
    13         scanf("%d",&h[i]);
    14       maxh=max(maxh,h[i]);
    15      }
    16      memset(f,127/3,sizeof(f));
    17      for (i=h[1];i<=maxh;i++)
    18      f[1][i]=(h[1]-i)*(h[1]-i);
    19       for (i=2;i<=n;i++)
    20       {
    21         go=h[i-1];
    22          for (j=h[i];j<=maxh;j++)
    23          {
    24             int tmp=(j-h[i])*(j-h[i]);
    25              int pre=2e9;
    26              for (l=go;l<=maxh;l++)
    27              {
    28                 int tmpp=f[i-1][l]+c*abs(j-l)+tmp;
    29                 if (tmpp<f[i][j])
    30                 {
    31                     f[i][j]=tmpp;
    32                     go=l;
    33                 }
    34                  if (tmpp<pre) pre=tmpp;
    35                  else
    36                   break;
    37              }
    38          }
    39       }
    40       int ans=2e9;
    41     for (i=h[n];i<=maxh;i++)
    42      ans=min(ans,f[n][i]);
    43     cout<<ans;
    44 }
  • 相关阅读:
    锐浪报表(Grid++Report)问题-子报表获取不到父报表参数问题解决
    C#PictureBox实现一直显示提示信息
    C#.Net ComboBox控件设置DropDownList之后背景颜色问题,以及发现的微软的一个BUG
    Visual Studio 2019移除/禁用Live Share按钮
    robotframework导入selenium2library变红
    robotframework selenium2library中关键字缺失的问题
    Jmeter之JSON提取器的使用
    Jmeter中unicode转码问题处理
    Jmeter之关联接口处理
    jmeter之用户自定义的变量
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7096148.html
Copyright © 2020-2023  润新知