[POI2015]Myjnie

题目大意:

有\(n(n\le50)\)家洗车店从左往右排成一排,每家店都有一个正整数价格\(d_i\)。

有\(m(m\le4000)\)个人要来消费,第\(i\)个人会选择\(a_i\sim b_i\)这些店中最便宜的一个进行一次消费。但是如果这个最便宜的价格大于\(c_i\),那么这个人就不洗车了。

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

思路:

将\(c\)离散化后进行区间DP。

用\(f_{i,j,k}\)表示区间\([i,j]\)最小值为\(k\)的最大收益,\(g_{i,j,k}\)表示\(f\)的后缀\(\max\),\(h_{i,j}\)表示当前区间内经过\(i\)点,费用限制\(\ge j\)的人数。

设\(k\)对应的离散化前原数为\(t_k\),枚举\(k\)出现的位置\(x\),转移方程为:

\[f_{i,j,k}=\max\{g_{i,x-1,k}+g_{x+1,j,k}+h_{x,k}\times t_k\}。
\]

由于要构造一种方案,在DP时记录转移即可。

时间复杂度\(\mathcal O(n^3m)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=51,M=4001;
int a[M],b[M],c[M],d[N],tmp[M],f[N][N][M],g[N][N][M],p[N][N][M],last[N][N][M],h[N][M];
void dfs(const int &i,const int &j,const int &k) {
const int &p=::p[i][j][k];
if(i!=p) dfs(i,p-1,last[i][j][k]);
if(j!=p) dfs(p+1,j,last[i][j][k]);
d[p]=tmp[last[i][j][k]];
}
int main() {
const int n=getint(),m=getint();
for(register int i=1;i<=m;i++) {
a[i]=getint();
b[i]=getint();
tmp[++tmp[0]]=c[i]=getint();
}
std::sort(&tmp[1],&tmp[tmp[0]]+1);
tmp[0]=std::unique(&tmp[1],&tmp[tmp[0]]+1)-&tmp[1];
for(register int i=1;i<=m;i++) {
c[i]=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,c[i])-tmp;
}
for(register int i=n;i>=1;i--) {
for(register int j=i;j<=n;j++) {
for(register int k=i;k<=j;k++) {
std::fill(&h[k][1],&h[k][tmp[0]]+1,0);
}
for(register int k=1;k<=m;k++) {
if(i<=a[k]&&b[k]<=j) {
for(register int i=a[k];i<=b[k];i++) h[i][c[k]]++;
}
}
for(register int k=i;k<=j;k++) {
for(register int i=tmp[0];i>1;i--) h[k][i-1]+=h[k][i];
}
for(register int k=tmp[0];k>=1;k--) {
for(register int x=i;x<=j;x++) {
const int t=g[i][x-1][k]+g[x+1][j][k]+h[x][k]*tmp[k];
if(t>=f[i][j][k]) {
f[i][j][k]=t;
p[i][j][k]=x;
}
}
g[i][j][k]=f[i][j][k];
last[i][j][k]=k;
if(k!=tmp[0]&&g[i][j][k+1]>g[i][j][k]) {
g[i][j][k]=g[i][j][k+1];
p[i][j][k]=p[i][j][k+1];
last[i][j][k]=last[i][j][k+1];
}
}
}
}
dfs(1,n,1);
printf("%d\n",g[1][n][1]);
for(register int i=1;i<=n;i++) {
printf("%d%c",d[i]," \n"[i==n]);
}
return 0;
}

[POI2015]Myjnie的更多相关文章

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

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

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

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

  3. bzoj4380[POI2015]Myjnie dp

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

  4. bzoj [POI2015]Myjnie

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

  5. BZOJ4380 : [POI2015]Myjnie

    将$c$离散化,设: $f[i][j][k]$为区间$[i,j]$最小值为$k$的最大收益. $g[i][j][k]$为$\max(g[i][j][k..m])$. $h[i][j]$为对于当前DP区 ...

  6. BZOJ 4380 [POI2015]Myjnie | DP

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

  7. 【BZOJ】4380: [POI2015]Myjnie

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

  8. 2018.10.22 bzoj4380: [POI2015]Myjnie(区间dp)

    传送门 区间dp好题. f[i][j][k]f[i][j][k]f[i][j][k]表示区间[i,j][i,j][i,j]最小值为kkk时的最大贡献. 然后可以枚举端点转移. 当时口胡到这儿就不会了. ...

  9. @bzoj - 4380@ [POI2015] Myjnie

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有 n 家洗车店从左往右排成一排,每家店都有一个正整数价格 p[ ...

随机推荐

  1. vue中使用cookie记住用户上次选择(本次例子中为下拉框)

    最近工作中碰到一个需求,添加一条数据时,自动记住上次选择的下拉框的数据,刚开始觉得没思路,后来请教了项目组长,组长直接一句,这不很简单吧,直接用cookie,我:....... 好吧,都王的差不多了, ...

  2. WCF ServiceContract,OperationContract

    代码如下 [ServiceContract] //服务协定定义 using System.ServiceModel; public interface IInterface1 { [Operation ...

  3. pip安装遇到问题

    安装pip之后,在cmd下输入 pip --version始终提示: Unknown option:versionDid not provide a command自己安装步骤没错,怎么想也不明白,无 ...

  4. [How to] Phoenix 与 CDH5.4.2 HBase的整合

    1.简介 Phoenix将SQL带回到了NOSQL的世界,其在HBase之上做了一个layer,客户端通过SQL调用Phoenix,Phoenix在转化为HBase客户算API进行访问HBase,其很 ...

  5. 洛谷P2015二叉苹果树

    传送门啦 树形 $ dp $ 入门题,学树形 $ dp $ 的话,可以考虑先做这个题. $ f[i][j] $ 表示在 $ i $ 这棵子树中选 $ j $ 个苹果的最大价值. include #in ...

  6. opencv(4)实现数据增加小工具

    数据增加(data augmentation),作为一种深度学习中的常用手段,数据增加对模型的泛化性和准确性都有帮助.数据增加的具体使用方式一般有两种,一种是实时增加,比如在Caffe中加入数据扰动层 ...

  7. ZooKeeper常见问题

    转载自原文:zookeeper(二)常见问题汇总 一.为什么zookeeper要部署基数台服务器? 所谓的zookeeper容错是指,当宕掉几个zookeeper服务器之后,剩下的个数必须大于宕掉的个 ...

  8. 高版本SQL备份在低版本SQL还原问题

    问题描述: 高版本SQL备份在低版本SQL还原问题(出现媒体簇的结构不正确)      分析原因: SQL版本兼容问题,SQL SERVER兼容级别是用作向下兼容用,高版本的SQL备份在低版本中不兼容 ...

  9. Python 安装 pytesser 处理验证码出现的问题

    今天这个问题困扰了我好久,开始直接用 pip install pytesseract 安装了 pytesseract 然后出现了如下错误 Traceback (most recent call las ...

  10. 结合Python代码介绍音符起始点检测 (onset detection)

    本文由 meelo 原创,请务必以链接形式注明 本文地址 音符起始点检测介绍 音符起始点检测(onset detection)是音乐信号处理中非常重要的一个算法.节拍和速度(tempo)的检测都会基于 ...