@description@

有 n 家洗车店从左往右排成一排,每家店都有一个正整数价格 p[i]。

有 m 个人要来消费,第 i 个人会驶过第 a[i] 个开始一直到第 b[i] 个洗车店,且会选择这些店中最便宜的一个进行一次消费。但是如果这个最便宜的价格大于 c[i],那么这个人就不洗车了。

请给每家店指定一个价格,使得所有人花的钱的总和最大。

input

第一行包含两个正整数 n, m(1<=n<=50,1<=m<=4000)。

接下来 m 行,每行包含三个正整数 a[i], b[i], ci

output

第一行输出一个正整数,即消费总额的最大值。

第二行输出 n 个正整数,依次表示每家洗车店的价格 p[i],要求 1<=p[i]<=500000。

若有多组最优解,输出任意一组。

sample input

7 5

1 4 7

3 7 13

5 6 20

6 7 1

1 2 5

sample output

43

5 5 13 13 20 20 13

@solution@

首先,洗车店的价格一定是某顾客的 c 值,否则可以通过调整变得更优。

像这样的区间最值相关问题可以考虑其笛卡尔树的结构。比如这道题就可以用笛卡尔树来 dp。

具体来讲,我们定义状态 dp(i, j, k),表示区间 [i, j] 的最小值为 k 能够取得的最大利益。根据最先的结论,我们 k 的取值只有 O(m) 个。

通过枚举 [i, j] 的最小值位置 p,我们可以进行转移:

\[dp(i, j, k) = dp(i, p-1, x) + dp(p+1, j, y) + f(i, j, p, k)
\]

其中要求 x, y >= k,权值函数 f(i, j, p, k) 表示这一个状态能够赚得的顾客利益。

f(i, j, p, k) 会计算到哪些顾客呢?假如第 q 个顾客被计算到了,那么必然有 i <= a[q] <= p <= b[q] <= j 且 c[q] >= k。

通过从大到小枚举 k,可以快速地维护 f。

我们通过维护后缀最大值,就可以不必再枚举 x 和 y。

因为要输出方案,记得记录当前状态是怎么转移过来的。最后递归输出即可。

总时间复杂度 O(n^3*m)。

@accepted code@

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 50;
const int MAXM = 4000;
struct node{
int le, ri;
int lim;
}a[MAXM + 5];
bool operator < (node a, node b) {
return a.lim < b.lim;
}
int n, m;
int ans[MAXN + 5];
int mx[MAXN + 5][MAXN + 5][MAXM + 5];
int dp[MAXN + 5][MAXN + 5][MAXM + 5];
int val[MAXN + 5][MAXN + 5][MAXN + 5];
int pre[MAXN + 5][MAXN + 5][MAXM + 5];
int mxpos[MAXN + 5][MAXN + 5][MAXM + 5];
void GetAnswer(int le, int ri, int p) {
if( mx[le][ri][p] == 0 ) {
for(int i=le;i<=ri;i++)
ans[i] = a[p].lim;
return ;
}
int q = mxpos[le][ri][p];
int r = pre[le][ri][q];
ans[r] = a[q].lim;
GetAnswer(le, r-1, q);
GetAnswer(r+1, ri, q);
}
int main() {
scanf("%d%d", &n, &m);
for(int i=1;i<=m;i++)
scanf("%d%d%d", &a[i].le, &a[i].ri, &a[i].lim);
sort(a+1, a+m+1);
for(int len=1;len<=n;len++)
for(int i=1;i+len-1<=n;i++) {
int j = i + len - 1;
for(int k=m;k>=1;k--) {
if( i <= a[k].le && a[k].ri <= j ) {
for(int l=i;l<=j;l++) {
if( a[k].le <= l && l <= a[k].ri )
val[i][j][l]++;
if( mx[i][l-1][k] + mx[l+1][j][k] + val[i][j][l]*a[k].lim > dp[i][j][k] ) {
pre[i][j][k] = l;
dp[i][j][k] = mx[i][l-1][k] + mx[l+1][j][k] + val[i][j][l]*a[k].lim;
}
}
}
if( k == m || dp[i][j][k] >= mx[i][j][k+1] ) {
mx[i][j][k] = dp[i][j][k];
mxpos[i][j][k] = k;
}
else {
mx[i][j][k] = mx[i][j][k+1];
mxpos[i][j][k] = mxpos[i][j][k+1];
}
}
}
printf("%d\n", mx[1][n][1]);
GetAnswer(1, n, 1);
for(int i=1;i<=n;i++)
printf("%d ", ans[i]);
puts("");
}

@details@

其实不需要离散化,因为即使 c 值重复也影响不大。

一开始因为区间 dp 的某些错误 dp 方式 WA 了几次(捂脸)。

@bzoj - 4380@ [POI2015] Myjnie的更多相关文章

  1. BZOJ 4380 [POI2015]Myjnie | DP

    链接 BZOJ 4380 题面 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i]. 有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗车店,且会选择这些店中最便宜的一个 ...

  2. 【BZOJ 4380】4380: [POI2015]Myjnie (区间DP)

    4380: [POI2015]Myjnie Description 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i].有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗 ...

  3. 【BZOJ】4380: [POI2015]Myjnie

    题解 区间dp,先离散化所有价值 \(f[i][j][k]\)表示\([i,j]\)区间里最小值为\(k\)的价值最大是多少 只考虑\(i <= a <= b <= j\)的区间,枚 ...

  4. BZOJ 4380 Myjnie 区间DP

    4380: [POI2015]Myjnie Time Limit: 40 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 162  Solved: ...

  5. bzoj [POI2015]Myjnie

    [POI2015]Myjnie Time Limit: 40 Sec Memory Limit: 256 MBSec Special Judge Description 有n家洗车店从左往右排成一排, ...

  6. [POI2015]Myjnie

    [POI2015]Myjnie 题目大意: 有\(n(n\le50)\)家洗车店从左往右排成一排,每家店都有一个正整数价格\(d_i\). 有\(m(m\le4000)\)个人要来消费,第\(i\)个 ...

  7. 【BZOJ4380】[POI2015]Myjnie 区间DP

    [BZOJ4380][POI2015]Myjnie Description 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i].有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[ ...

  8. bzoj4380[POI2015]Myjnie dp

    [POI2015]Myjnie Time Limit: 40 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 368  Solved: 185[S ...

  9. bzoj 4386: [POI2015]Wycieczki

    bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...

随机推荐

  1. 前端js框架引入管理bundle.js

    最先在ionic中看到bundle.js,,,然而它不是一个框架

  2. nginx 限制ip的请求频率

    需要注意,这个很容易误伤 还需要结合别的办法进行共同配置 总是有人很清闲的扫我的网站 ,所以要限制一下了 先来看看没有限制的时候,并发10 100次 服务器一直在正常响应  限制一下,之后再测试一下 ...

  3. Springmvc使用阿里巴巴的fastjson传输到前台中文乱码的解决方案,他娘的大家都少制造垃圾,学习过程将会多么快乐

    弄了大概七八个小时吧 都他妈比的抄来抄去,一分一秒的去试错 最终参考这个问题解决了乱码的情况https://bbs.csdn.net/topics/392169549 412 需要在springmvc ...

  4. 洛谷P1979 [NOIP2013提高组Day2T3]华容道

    P1979 华容道 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少 ...

  5. 启动Hadoop时,DataNode启动后一会儿自动消失的解决方法

    查看slaver1/2的logs,发现 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for ...

  6. Vue调试神器之Vue.js devTools

    Vue项目中使用Vue.js devTools这款调试神器,可以极大程度的提高我们的开发效率. 安装 1.打开Chrome网上应用商店安装插件(自墙),直接搜索devTools安装即可.贵宾传送阵,请 ...

  7. SQL优化神器 - Tosska SQL Tuning Expert Pro for Oracle

    SQL Tuning Expert Pro for Oracle 是Tosska 公司推出的划时代SQL优化工具.它可以帮助SQL开发人员和DBA: 找到最快的等价SQL: 调整执行计划: 管理SQL ...

  8. python 结构化的数据

  9. CMake学习笔记二

    CMake预定义变量 PROJECT_SOURCE_DIR 工程的根目录 PROJECT_BINARY_DIR 运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build ...

  10. 移动端以及 PC浏览器页面分享到朋友圈等的功能实现

    我们经常可以在一些 app上看到分享到朋友圈.微信好友.qq好友等功能,例如 饿了么.美团等 app,下单之后就会弹出给好友发红包的 modal窗,这在 app上很常见,app的权限可以很大,甚至连启 ...