http://cogs.pro:8080/cogs/problem/problem.php?pid=2240

与洛谷P2885几乎一致,https://www.luogu.org/problemnew/show/P2885,双倍经验。

定义dp[i][j]表示前i棵树的最大花费并且第i 棵树高度为j的。

我们可以想到这某一棵树的高度与它前边的树有直接的关系,不难有一种想法。

枚举第几棵树1->n

枚举每棵树的高度$h[i]-> max \{ h[1],h[2]...h[n] \} $

枚举第i棵树前边那棵树也就是第i-1棵树的高度。

现在我们想状态转移方程:

当第i棵数的高度为j时,那么需要花费$(j-h[i])^2$,与前边好要有连起来那就需要找到abs(j-dp[i-1][h[i]->maxh])中的最小值。

所以$dp[i][j]=min(dp[i][j],(j-h[i]^2+(j-dp[i-1][h[i]->maxh]) \times c))$.

那么算法时间复杂度为$O(n \times h \times h)$.

时间复杂度虽然比较高,奈何cogs数据比较水啊,勉强可以过。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int min(int a,int b){ return a<b?a:b; }
int n,a[],c,ans,f[][];
inline int read()
{
char c=getchar();
int x=;
while(c<''||c>'') c=getchar();
while(c>=''&&c<='')
x=(x<<)+(x<<)+c-,c=getchar();
return x;
}
int main()
{
freopen("phonewire.in","r",stdin);
freopen("phonewire.out","w",stdout);
ans=0x7fffffff;
scanf("%d%d",&n,&c);
for(int i=;i<=n;i++)a[i]=read();
for(int i=;i<=n;i++)
for(int j=;j<=;j++)
f[i][j]=;
for(int i=;i<=;i++)f[][i]=(i-a[])*(i-a[]);
for(int i=;i<=n;i++)
{
for(int j=a[i];j<=;j++)
{
for(int k=a[i-];k<=;k++)
{
f[i][j]=min(f[i][j],f[i-][k]+(j-a[i])*(j-a[i])+abs(k-j)*c);
}
}
}
for(int i=;i<=;i++)ans=min(ans,f[n][i]);
printf("%d",ans);
fclose(stdin);fclose(stdout);
}

然而洛谷上不吸氧的话就需要优化一下了(以下话语来自洛谷管理---redbag)

不难发现,每次转移是个开口向上的二次函数(可以自己算算),然后我们枚举上一棵树的高度的过程中,

如果随着高度的增加费用增加了,就可以不用继续转移了。

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
char s;
int k=,base=;
while((s=getchar())!='-'&&s!=EOF&&!(s>=''&&s<=''));
if(s==EOF)exit();
if(s=='-')base=-,s=getchar();
while(s>=''&&s<='')
{
k=k*+(s-'');
s=getchar();
}
return k*base;
}
inline void write(int x)
{
if(x<)
{
putchar('-');
write(-x);
}
else
{
if(x/)write(x/);
putchar(x%+'');
}
}
int n,c,p,x,s,mh;
int h[];
int f[][];
int main()
{
n=read();
c=read();
for (register int i=; i<=n; i++)
{
h[i]=read();
if (h[i]>mh) mh=h[i];
}
memset(f,,sizeof(f));
for (register int i=h[]; i<=; i++) f[][i]=(i-h[])*(i-h[]);
for (register int i=; i<=n; i++)
{
for (register int j=h[i]; j<=mh; j++) //hm:电线杆的最大高度
{
s=(j-h[i])*(j-h[i]);//先算出来快些?
p=;
for (register int k=h[i-]; k<=mh; k++)
{
x=f[i-][k]+s+c*abs(k-j);
//下面和这一句是等效的,似乎快点?f[i][j]=min(f[i][j],x);
if (x<f[i][j])
{
f[i][j]=x;
}
if (x>p) break;//比上一个更多就不用转移了
p=x;
}
}
}
int ans=f[n][h[n]];
for (register int i=h[n]+; i<=; i++) ans=min(ans,f[n][i]); //找答案
printf("%d",ans);
return ;
}

[题解] cogs 2240 架设电话线路的更多相关文章

  1. 「 COGS 2240 」 X 「 Luogu P2885 」 架设电话线

    解题思路 首先很容易就想到了一个二维的朴素的 $dp$. 设 $dp[i][j]$ 表示第 $i$ 个位置的电话线杆的高度为 $j$ 时的最小花费,就需要枚举第 $i$ 个电话线杆.第 $i$ 个电话 ...

  2. 「Poetize7」电话线路

    描述 每台电话都有一个独一无二的号码,用一个十位的十进制数字串表示.电话a和b之间能直接通信,当且仅当“a与b之间仅有一个数字不同”,或者“交换a的某 两位上的数字后,a与b相同”.而a.b之间建立通 ...

  3. [题解] cogs 1669 神秘的咒语

    http://cogs.pro:8080/cogs/problem/problem.php?pid=1669 "The Real Incantation is Their Common In ...

  4. dp专练

    dp练习. codevs 1048 石子归并 区间dp #include<cstdio> #include<algorithm> #include<cstring> ...

  5. 洛谷 P1991 无线通讯网 题解

    P1991 无线通讯网 题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. 洛谷P1991无线通讯网[kruskal | 二分答案 并查集]

    题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...

  8. P1991 无线通讯网 最小生成树

    题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...

  9. FAX modem和传真协议简介

    FAX就是传真,传真通信是使用传真机,借助公用通信网或其他通信线路传送图片,文字等信息,并在接收方获得发送原件系统的副本的一种通信方式.传真通信是现代图像通信的重要组成部分,它是目前采用公用电话网传送 ...

随机推荐

  1. Codeforces - 1117E - Crisp String - 进制 - 交互

    https://codeforces.com/problemset/problem/1117/E 就用abc表示数字来给每个数编码,编完直接问出移动的结果,反构造就行了,比C和D还简单. #inclu ...

  2. 算法学习--Day1

    为了冲刺研究生初试,我准备在课余时间捡起往日的算法.多多练习算法题目,提前准备算法的机试. 今天是4月14日,距离算法考试还有两个月的时间吧,这两个月的所学所得我就都记录在这里了.不仅仅包括算法的准备 ...

  3. bzoj 2067: [Poi2004]SZN【贪心+二分+树形dp】

    第一问就是Σ(deg[u]-1)/2+1 第二问是二分,判断的时候考虑第一问的贪心规则,对于奇度数的点,两两配对之后一条延伸到上面:对于欧度数的点,两两配对或者deg[u]-2的点配对,然后一条断在这 ...

  4. 前端开发常用cmd命令

    windows打开命令行 开始->运行->键入cmd 也可通过附件查找到命令提示符,右键属性为其设置快捷键 快捷键 更改路径 d:        // 切换到d盘 cd  <fold ...

  5. Luogu P1607 庙会班车【线段树】By cellur925

    题目传送门 据说可以用贪心做?算了算了...我都不会贪.... 开始想的是用线段树,先建出一颗空树,然后输进区间操作后就维护最大值,显然开始我忽视了班车的容量以及可以有多组奶牛坐在一起的信息. 我们肯 ...

  6. NOIp 2015信息传递【tarjan/拓扑/并查集】

    一道好的NOIp题目,在赛场上总能用许多算法A掉.比如这道和关押罪犯. 题目传送门 法一:tarjan在有向图中跑最小环 有人从别人口中得知自己信息,等效于出现了一个环.于是 这就变成了一个有向图ta ...

  7. DP+高精度 URAL 1036 Lucky Tickets

    题目传送门 /* 题意:转换就是求n位数字,总和为s/2的方案数 DP+高精度:状态转移方程:dp[cur^1][k+j] = dp[cur^1][k+j] + dp[cur][k]; 高精度直接拿J ...

  8. 注册jdbc驱动的三种方式

    java.sql.DriverManger类简介   java的驱动管理类.管理一组 JDBC 驱动程序. javax.sql.DataSource 接口是 JDBC 2.0 API 中的新增内容,它 ...

  9. (转)Unity优化之减少Drawcall

    转载:http://www.jianshu.com/p/061e67308e5f Unity GUI(uGUI)使用心得与性能总结 背景和目的 小哈接触Unity3D也有一段时间了,项目组在UI解决方 ...

  10. BigDecimal取余运算

    取余运算在编程中运用非常广泛,对于BigDecimal对象取余运算可以通过divideAndRemainder方法实现. public BigDecimal[] divideAndRemainder( ...