译文及题解 电话线Telephone Wire(动态规划)

电话线Telephone Wire
[USACO07NOV]

Question In English(BY USACO)
中文翻译(翻译自Stockholm_Sun)

Telephone Wire
电话线

Farmer John’s cows are getting restless about their poor telephone service; they want FJ to replace the old telephone wire with new, more efficient wire. The new wiring will utilize N (2 ≤ N ≤ 100,000) already-installed telephone poles, each with some heighti meters (1 ≤ heighti ≤ 100). The new wire will connect the tops of each pair of adjacent poles and will incur a penalty cost C × the two poles’ height difference for each section of wire where the poles are of different heights (1 ≤ C ≤ 100). The poles, of course, are in a certain sequence and can not be moved.
农夫约翰的牛们对他们烂到爆的电话服务感到焦躁不安;他们想让农夫约翰把旧的电线换成全新的并且更高效的电线。这组新的线路将会利用N(2 ≤ N ≤ 100,000) 条已经安装了的电线杆,每个电话杆都有H(i)米高(1 ≤ H(i) ≤ 100)。这个新的电话线将会连接每一对相邻的电线杆,并且会产生(C*两电线杆高度之差)的代价(1 ≤ C ≤ 100)。当然,电线杆是有序的而且不能被移走。

Farmer John figures that if he makes some poles taller he can reduce his penalties, though with some other additional cost. He can add an integer X number of meters to a pole at a cost of X2.
农夫约翰想到了这样一个事实:如果他让一些电线杆变得更高,那么他就可以减少他的花费,尽管还有一些额外的花费。它能够花X^2的代价给一个电线杆增加X的高度(附注:可以给任意电线杆增加任意正整数高度)。

Help Farmer John determine the cheapest combination of growing pole heights and connecting wire so that the cows can get their new and improved service.
帮助农夫约翰决定出最划算的增长电线杆高度的方案,然后连接电线以至于奶牛们可以得到他们全新并改善的服务。

Input & Output Format
输入输出格式

Input Format
Line 1: Two space-separated integers: N and C
Lines 2..N+1: Line i+1 contains a single integer: heighti
输入格式:
第1行:两个用空格分开的整数:N和C
第2至N+1行:第i+1包含一个单独的整数:H(i)

Output Format
Line 1: The minimum total amount of money that it will cost Farmer John to attach the new telephone wire.
输出格式:
第1行:农夫约翰连接新电话线所花费的最少总钱数。

Samples Input & Samples Output
输入输出样例

Samples Input
输入样例#
5 2
2
3
5
1
4

扫描二维码关注公众号,回复: 2580059 查看本文章

Samples Output
输出样例#1:
15

思路

看到题目,我们考虑动态规划,先假设f[ x ]为在x之前花费的最小价格,但是我们需要考虑为电线杆增加高度。
所以考虑升维,既然高度未知,我就升维,f[ x ][ h ]就是前x个电线杆,且第x个高度为h的最小花费。
我们就可以枚举前一个的高度和当前杆子的高度,从前一个转移而来:f[i][j]=min{f[i-1][k]+(j-h[i])*(j-h[i])+abs(j-k)*p};这个就是状态转移方程。
最后答案为f[n][i]max。

代码

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
#include<algorithm>
using namespace std;  
long long i,j;
long long k,n,p;
long long h[100001],f[100001][101];

long long r()
{
    long long p=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
        {
            f=-1;
        }
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        p=p*10+c-'0';
        c=getchar();
    }
    return p*f;
}
char chr;

int main()
{
//  freopen("out.txt","w",stdout);
    n=r(),p=r();
    long long maxx=0;
    for(i=1;i<=n;i++)
    {
        h[i]=r();
        if(h[i]>maxx)
        maxx=h[i];
    }

    memset(f,0x7f7f7f,sizeof(f));

    for(i=h[1];i<=100;i++)
    f[1][i]=(i-h[1])*(i-h[1]);

    long long ans=0x7fffffff;
    for(i=2;i<=n;i++)
    for(j=h[i];j<=maxx;j++)
    {
        ans=0x7fffffff;
        for(k=h[i-1];k<=maxx;k++)
        {
            if(f[i-1][k]+(j-h[i])*(j-h[i])+abs(j-k)*p<f[i][j])
            f[i][j]=f[i-1][k]+(j-h[i])*(j-h[i])+abs(j-k)*p;
            if(f[i][j]>ans) break;
            else ans=f[i][j];
        }
    }
    ans=0x7fffffff;
    for(i=h[n];i<=100;i++)
    ans=min(ans,f[n][i]);
    cout<<ans;
    return 0;
}
/*

*/

这里写图片描述

猜你喜欢

转载自blog.csdn.net/Stockholm_Sun/article/details/78408313