P2885 [USACO07NOV]电话线Telephone Wire——Chemist
题目:
https://www.luogu.org/problemnew/show/P2885
由于把每一根电线杆增加多少高度不确定,所以很难直接通过某种方法算出答案,考虑动态规划。
状态:f [ i ] [ j ]表示当第i根电线杆的高度为j时的最小代价和。
转移:当前电线杆的高度只会影响它下一个电线杆的高度,所以就是用前一维的答案来更新后一维。在计算第i根电线杆和第i-1根电线杆时需要计算三部分答案:1.将第i根电线杆增加到j高度的代价 ( j - h [ i ])*(j - h [ i ] )。2.到第i-1根电线杆时的最小花费f [ i-1 ] [ k ](由于我们并不知道第i-1根电线杆的高度,所以需要枚举第i-1根电线杆的高度k)3. 第i根电线杆到第i-1根电线杆之间电线的代价( j - k )*C
由此我们得到转移方程:f [ i ] [ j ] = ( j - h [ i ] )^2 + min( f [ i - 1 ] [ k ] + | j - k |*C )
然而这需要我们用三重循环枚举,时间复杂度是O( n*C*C ),会超时(好像有人用这个卡过了。。。)。
优化:
我们把绝对值拆开来可以得到一个分段函数:
f [ i ] [ j ] = ( j - h [ i ] )^2 + min( f [ i - 1 ] [ k ] + j * C - k * C) ,j>=k
f [ i ] [ j ] = ( j - h [ i ] )^2 + min( f [ i - 1 ] [ k ] + k * C - j * C ) ,j < k
我们把 j * C从min中提出来,就变成了:
f [ i ] [ j ] = ( j - h [ i ] )^2 + j * C + min( f [ i - 1 ] [ k ] - k * C) ,j>=k
f [ i ] [ j ] = ( j - h [ i ] )^2 - j * C + min( f [ i - 1 ] [ k ] + k * C ) ,j < k
我们可以发现,min里面的东西只与k和i有关而与j无关,所以我们可以在外层枚举i,在内层预处理出f [ i - 1 ] [ k ] - k * C的前缀最小值和f [ i - 1 ] [ k ] + k * C的后缀最小值,然后再枚举j,这是就可以直接O(1)调用min(...)了。
同时由于每一维的状态只与上一维有关且不需要记录答案,所以可以通过滚动数组来将空间复杂度进一步优化到O(C)。
代码:(注意赋初值等细节)
#include<bits/stdc++.h>
using namespace std;
int read()
{
int ans=;
char ch=getchar(),last=' ';
while(ch<''||ch>'')
{last=ch;ch=getchar();}
while(ch>=''&&ch<='')
{ans=ans*+ch-'';ch=getchar();}
if(last=='-')ans=-ans;
return ans;
}
const int M=1e5+,inf=1e9+;
int n,C,h[M],f[M][],m;
//f[i][j]表示第i根电线杆的高度为j时的最小代价和
int l[],r[];
int main()
{
n=read();C=read();
memset(f,0x3f,sizeof(f));
for(int i=;i<=n;i++)
h[i]=read(),m=max(m,h[i]);
for(int i=h[];i<=m;i++)
f[][i]=(i-h[])*(i-h[]);
for(int i=;i<=n;i++)
{
l[h[i-]-]=inf;
r[m+]=inf;
for(int k=h[i-];k<=m;k++)
l[k]=min(l[k-],f[i-][k]-k*C);
for(int k=m;k>=h[i];k--)
r[k]=min(r[k+],f[i-][k]+k*C);
for(int j=h[i-];j<=m;j++)
if(j>=h[i])f[i][j]=l[j]+(j-h[i])*(j-h[i])+C*j;
for(int j=m;j>=h[i];j--)
f[i][j]=min(f[i][j],r[j]-C*j+(j-h[i])*(j-h[i]));
}
int ans=inf;
for(int i=h[n];i<=m;i++)
ans=min(ans,f[n][i]);
printf("%d\n",ans);
return ;
}
P2885 [USACO07NOV]电话线Telephone Wire——Chemist的更多相关文章
- P2885 [USACO07NOV]电话线Telephone Wire
P2885 [USACO07NOV]电话线Telephone Wire 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话 ...
- [USACO07NOV]电话线Telephone Wire
[USACO07NOV]电话线Telephone Wire 时间限制: 1 Sec 内存限制: 128 MB 题目描述 电信公司要更换某个城市的网线.新网线架设在原有的 N(2 <= N &l ...
- [luoguP2885] [USACO07NOV]电话线Telephone Wire(DP + 贪心)
传送门 真是诡异. 首先 O(n * 100 * 100) 三重循环 f[i][j] 表示到第 i 个柱子,高度是 j 的最小花费 f[i][j] = min(f[i - 1][k] + abs(k ...
- 【USACO07NOV】电话线Telephone Wire
题目描述 电信公司要更换某个城市的网线.新网线架设在原有的 N(2 <= N <= 100,000)根电线杆上, 第 i 根电线杆的高度为 height_i 米(1 <= heigh ...
- [USACO 07NOV]电话线Telephone Wire
题目描述 Farmer John's cows are getting restless about their poor telephone service; they want FJ to rep ...
- DP+滚动数组 || [Usaco2007 Nov]Telephone Wire 架设电话线 || BZOJ 1705 || Luogu P2885
本来是懒得写题解的…想想还是要勤发题解和学习笔记…然后就滚过来写题解了. 题面:[USACO07NOV]电话线Telephone Wire 题解: F[ i ][ j ] 表示前 i 根电线杆,第 i ...
- 【动态规划】bzoj1705: [Usaco2007 Nov]Telephone Wire 架设电话线
可能是一类dp的通用优化 Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设 ...
- BZOJ_1705_[Usaco2007 Nov]Telephone Wire 架设电话线_DP
BZOJ_1705_[Usaco2007 Nov]Telephone Wire 架设电话线_DP Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是 ...
- bzoj1705[Usaco2007 Nov]Telephone Wire 架设电话线(dp优化)
1705: [Usaco2007 Nov]Telephone Wire 架设电话线 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 441 Solved: ...
随机推荐
- [Bzoj3209]花神的数论题(数位dp)
3209: 花神的数论题 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2633 Solved: 1182[Submit][Status][Disc ...
- LINUX 下 ipv6 socket 编程
大家都知道,随着互联网上主机数量的增多,现有的32位IP地址已经不够用了,所以推出了下一代IP地址IPv6,写网络程序的要稍微改变一下现有的网络程序适应IPv6网络是相当容易的事.对于我们来说就是IP ...
- PCRE函数简介和使用示例
PCRE是一个NFA正则引擎,不然不能提供完全与Perl一致的正则语法功能.但它同时也实现了DFA,只是满足数学意义上的正则. PCRE提供了19个接口函数,为了简单介绍,使用PCRE内带的测试程序( ...
- SpringDataJPA入门2
SpringDataJPA实体概述 JPA提供了一种简单高效的方式来管理Java对象(POJO)到关系型数据库的映射,此类Java对象成为JPA实体或简称实体.实体通常与底层数据库中的单个关系表相关联 ...
- Failed to load resource: the server responded with a status of 404 (Not Found)
Failed to load resource: the server responded with a status of 404 (Not Found) 报错情况:图标加载失败 原因分析:路径错误 ...
- 微信小程序之 SideBar(侧栏分类)
项目目录: 模拟数据: utils / data.js function getSData() { var data = [ { "id": 1, "tree" ...
- MySQL基础笔记(三) 复杂查询
所谓复杂查询,指涉及多个表.具有嵌套等复杂结构的查询.这里简要介绍典型的几种复杂查询格式. 一.连接查询 连接是区别关系与非关系系统的最重要的标志.通过连接运算符可以实现多个表查询.连接查询主要包括内 ...
- 输入年份,然后打印出该年的万年历,以及标识出当天日期。相似于linux下的cal -y结果。
public class Permanent { public static boolean isLeapYear(int year){//能被4整除但不能被100整除.或者能被400整除 boole ...
- Kemans算法及其Python 实现
算法优缺点: 优点:容易实现缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢使用数据类型:数值型数据 算法思想 k-means算法实际上就是通过计算不同样本间的距离来判断他们的相近关系的,相近的就 ...
- Koa2学习(七)使用cookie
Koa2学习(七)使用cookie Koa2 的 ctx 上下文对象直接提供了cookie的操作方法set和get ctx.cookies.set(name, value, [options])在上下 ...