luogu2885
P2885 [USACO07NOV]电话线Telephone Wire
给出若干棵树的高度,你可以进行一种操作:把某棵树增高h,花费为h*h。
操作完成后连线,两棵树间花费为高度差*定值c。
求两种花费加和最小值。
输入输出样例
5 2
2
3
5
1
4
15 sol:显然暴力的dp很容易得到,dp[i][j]表示第i个高度为j个最小代价
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll S=; char ch=' '; bool f=;
while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
while(isdigit(ch)) {S=(S<<)+(S<<)+(ch-''); ch=getchar();}
return (f)?(-S):(S);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<) {putchar('-'); x=-x;}
if(x<) {putchar(x+''); return;}
write(x/); putchar(x%+'');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=,M=,inf=0x3f3f3f3f;
int n,c,hig[N],mx,ans;
int dp[N][M];
inline int sqr(int x){return x*x;}
int main()
{
freopen("luogu2885_data.in","r",stdin);
int i,j,k;
R(n); R(c);
for(i=;i<=n;i++)
{
R(hig[i]); mx=max(mx,hig[i]);
}
memset(dp,,sizeof dp);
dp[][hig[]]=;
for(i=;i<=mx-hig[];i++) dp[][hig[]+i]=i*i;
for(i=;i<=n;i++)
{
for(j=hig[i];j<=mx;j++) for(k=hig[i-];k<=mx;k++)
{
dp[i][j]=min(dp[i][j],dp[i-][k]+sqr(j-hig[i])+c*abs(j-k));
}
}
ans=inf;
for(i=hig[n];i<=mx;i++) ans=min(ans,dp[n][i]);
Wl(ans);
return ;
}
然后发现容易拆开abs分类讨论一下即可
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=; bool f=; char ch=' ';
while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
while(isdigit(ch)) {s=(s<<)+(s<<)+(ch^); ch=getchar();}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<) {putchar('-'); x=-x;}
if(x<) {putchar(x+''); return;}
write(x/); putchar((x%)+'');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=,inf=0x3f3f3f3f;
int n,c,mx,hig[N];
int dp[N][],mn[];
inline int sqr(int x){return x*x;}
int main()
{
freopen("luogu2885_data.in","r",stdin);
int i,j;
R(n); R(c);
for(i=;i<=n;i++) mx=max(mx,hig[i]=read());
memset(dp,,sizeof dp);
for(i=hig[];i<=mx;i++) dp[][i]=sqr(i-hig[]);
for(i=;i<=n;i++)
{
for(j=;j<=hig[i-]-;j++) mn[j]=inf;
for(j=hig[i-];j<=mx;j++) mn[j]=min(mn[j-],dp[i-][j]-c*j);
for(j=hig[i];j<=mx;j++) dp[i][j]=min(dp[i][j],mn[j]+sqr(j-hig[i])+c*j);
mn[mx+]=inf;
for(j=mx;j>=hig[i-];j--) mn[j]=min(mn[j+],dp[i-][j]+c*j);
for(j=hig[i-]-;j>=;j--) mn[j]=mn[hig[i-]];
for(j=hig[i];j<=mx;j++) dp[i][j]=min(dp[i][j],mn[j]+sqr(j-hig[i])-c*j);
// for(j=hig[i];j<=mx;j++) cout<<i<<' '<<j<<' '<<dp[i][j]<<endl; putchar('\n');
}
int ans=inf;
for(j=hig[n];j<=mx;j++) ans=min(ans,dp[n][j]);
Wl(ans);
return ;
}
ac
luogu2885的更多相关文章
随机推荐
- pycharm2019.2永久激活
Pycharm2019.2永久激活Pycharm官网在不到两个月内与2019.7.24更新到最新版本pycharm2019.2,不可说更新不快,对于"喜新厌旧"的我怎能错过新版本呢 ...
- Python函数知识点总结
1.函数的定义2.如何定义一个函数以及函数语法3.函数的调用4.函数的参数(形参,实参)以及参数的传递5.函数的返回值6.变量的作用域7.匿名函数8.嵌套函数和闭包9.装饰器10.函数思维导图 1.函 ...
- 关于ECharts甘特图的实现
对于使用ECharts图表的步骤,每种图表都是一致的,相信大家也都了解 此处只分享甘特图的option,代码如下: option: { title: { text: '项目实施进度表', left: ...
- springload热更新的优缺点
java开发web应用没有.net的方便快捷, 原因是传统开发模式下新增修改代码后要查看效果, 一般要重启应用, 导致浪费了许多无谓的时间,没有.net的高效, 任意更新文件实时生效. 但是有个叫sp ...
- js中拼接html代码时onclick参数问题
一.如果是int类型.可以直接传参 二.如果是字符串类型.需要加上引号 1.使用转义符号\转义引号: (\''+strings+'\') 2.使用" .比如: ("'+strin ...
- Oracle 找到引起账户锁定的IP
在ORACLE数据库中,如果没有修改过FAILED_LOGIN_ATTEMPTS的话,默认10次尝试失败后就会锁住用户.此时再登录数据库,就会遇到ORA-28000: the account is l ...
- 中国大学MOOC课程信息之数据分析可视化二
版权声明:本文为博主原创文章,转载 请注明出处:https://blog.csdn.net/sc2079/article/details/82318571 - 写在前面 本篇博客继续对中国大学MOOC ...
- linux目录太长怎么办?分享一点小技巧
在linux使用cd的时候,可能会遇到目录比较深的时候,这个时候总是cd一个很长的目录会很麻烦,那有没有什么比较方便的方法呢? 若是在两个目录中来回切换,这个时候可以使用cd - 这个命令,可以完成在 ...
- JavaScript 页面渲染
1. 从输入url到得到html的详细过程 1.1 加载资源的形式 输入 URL 或跳转页面 加载 html 1.2 加载一个资源的过程 浏览器根据DNS服务器得到域名的IP地址 向这个IP ...
- BZOJ 2095 [Poi2010]Bridges (二分+最大流判断混合图的欧拉回路)
题面 nnn个点,mmm条双向边(正向与反向权值不同),求经过最大边权最小的欧拉回路的权值 分析 见 commonc大佬博客 精髓就是通过最大流调整无向边的方向使得所有点的入度等于出度 CODE #i ...