\(\mathcal{Description}\)

  Link.

  有 \(n\) 支蜡烛,第 \(i\) 支的坐标为 \(x_i\),初始长度为 \(a_i\),每单位时间燃烧变短 \(1\) 直到长度为 \(0\)。你从 \(0\) 位置出发,每次可以向左或向右走 \(1\) 单位,走到一个蜡烛的位置可以吹熄蜡烛。求最多能保留的蜡烛长度之和。

  \(n\le300\)。

\(\mathcal{Solution}\)

  和 甲虫 这题比较像,可以说是相同思路的不同实现方法。问题的核心自然是费用提前计算,我们需要知道想要吹熄的蜡烛数量才能计算当前行动一步带来的总长度损失。注意到 \(n\) 较小,可以直接把这一信息记入状态。

  具体地,加入一支 \(x_{n+1}=a_{n+1}=0\) 的蜡烛,设按坐标排序后该蜡烛的下标为 \(p\)。令 \(f(l,r,0/1,k)~([l,r]\ni p,k\in[0,n])\) 表示当前经过了区间 \([l,r]\) 内的蜡烛位置,停留在 \(l/r\),还希望在这个区间以外获得 \(k\) 支蜡烛。通过忽略“蜡烛长度非负”这一限制,把最大化最大值转化成最大化任意值,可以轻松 DP 求解。复杂度 \(\mathcal O(n^3)\)。

\(\mathcal{Code}\)

/*~Rainybunny~*/

#include <bits/stdc++.h>

#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i ) typedef long long LL;
typedef std::pair<int, int> PII;
#define fi first
#define se second const int MAXN = 300;
const LL LINF = 1ll << 60;
int n;
LL f[MAXN + 5][MAXN + 5][2][MAXN + 5];
PII cdl[MAXN + 5]; inline LL dabs( const LL u ) { return u < 0 ? -u : u; }
inline void chkmax( LL& u, const LL v ) { u < v && ( u = v ); } int main() {
scanf( "%d", &n ), ++n;
rep ( i, 2, n ) scanf( "%d %d", &cdl[i].fi, &cdl[i].se ); std::sort( cdl + 1, cdl + n + 1 );
int p = std::lower_bound( cdl + 1, cdl + n + 1, PII( 0, 0 ) ) - cdl; rep ( i, 1, n ) rep ( j, i + 1, n ) rep ( t, 0, 1 ) rep ( k, 0, n ) {
f[i][j][t][k] = -LINF;
}
rep ( i, 0, n ) f[p][p][0][i] = 0;
LL ans = 0;
rep ( len, 0, n - 1 ) {
for ( int i = 0, l, r; i <= len; ++i ) {
if ( ( l = p - i ) <= 0 || ( r = p + len - i ) > n ) continue;
int x[2] = { cdl[l].fi, cdl[r].fi };
rep ( t, 0, 1 ) {
rep ( k, 0, n ) {
LL cur = f[l][r][t][k];
if ( cur == -LINF ) continue;
if ( !k ) { chkmax( ans, cur ); continue; }
if ( l > 1 ) {
chkmax( f[l - 1][r][0][k - 1], cur + cdl[l - 1].se
- dabs( x[t] - cdl[l - 1].fi ) * k );
chkmax( f[l - 1][r][0][k], cur
- dabs( x[t] - cdl[l - 1].fi ) * k );
}
if ( r < n ) {
chkmax( f[l][r + 1][1][k - 1], cur + cdl[r + 1].se
- dabs( x[t] - cdl[r + 1].fi ) * k );
chkmax( f[l][r + 1][1][k], cur
- dabs( x[t] - cdl[r + 1].fi ) * k );
}
}
}
}
}
printf( "%lld\n", ans );
return 0;
}

最新文章

  1. WAMP中phpMyAdmin登陆不了问题的解决方法
  2. hdoj 3501
  3. linux第9天 UDP
  4. Android UI开发详解之Fragment
  5. [liu yanling]测试用例的设计方法
  6. java学习面向对象之接口
  7. parentViewController
  8. Hadoop中MapReduce作业流程图
  9. 50、html补充
  10. 使用redis所维护的代理池抓取微信文章
  11. 关闭selinux服务
  12. 关于学习Vue的前置工作/技术储备
  13. Python数据库工具类MySQLdb使用
  14. android 获取 imei号码
  15. AjaxResult
  16. js url?callback=xxx xxx的介绍
  17. MVC的初步认识理论
  18. js面向对象设计之class中一些坑和技巧
  19. jvm字节码简介
  20. [linux基础学习]默认的目录介绍

热门文章

  1. JavaWeb中Session会话管理,理解Http无状态处理机制
  2. SpringMVC拦截器的应用
  3. Python多环境管理神器(pyenv)
  4. python基本数据类型与操作
  5. day 17 i++优先级大于 *i
  6. linux 安装mysql 可能遇到的小问题
  7. 《剑指offer》面试题32 - II. 从上到下打印二叉树 II
  8. 【get√】golang新手理解了一点点context
  9. Cesium中文网的朋友们
  10. css中设置背景图片适应屏幕