链接

BZOJ 4380

题面

有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。

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

题解

这道题……是一个正常的(?)区间DP。

先将所有c[i]离散化。

f[i][j][k]表示区间[i, j]内的店、最低价格为k,能取到的最大价值。这个最大价值包括所有“完全包含在[i, j]”内的顾客提供的价值。

g[i][j][k]表示区间[i, j]内的店、最低价格>=k,能取到的最大价值。

转移的时候,枚举最低价格k所在的位置p,采取类似分治的思想,设完全包含在[i, j]内、横跨位置p、且c[i] >= k的顾客有cnt[p][k]个,那么有:

\[f[i][j][k] = max_{p = i}^{j} g[i][p - 1][k] + g[p + 1][j][k] + k * cnt[p][k]
\]

这个cnt数组在每次枚举[i, j]的时候都预处理一下。

因为要输出方案,所以额外记录一下最优解都是在哪里取到的,最后dfs求出方案。

总复杂度是\(O(n^3m)\)。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define enter putchar('\n')
#define space putchar(' ')
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int N = 52, M = 4002;
int n, m, a[M], b[M], c[M], cnt[N][M], ans[N], lst[M], idx, f[N][N][M], g[N][N][M], gk[N][N][M];
short fp[N][N][M]; void dfs(int l, int r, int k){
int val = gk[l][r][k], pos = fp[l][r][val];
ans[pos] = lst[val];
if(pos > l) dfs(l, pos - 1, val);
if(pos < r) dfs(pos + 1, r, val);
} int main(){ read(n), read(m);
for(int i = 1; i <= m; i++)
read(a[i]), read(b[i]), read(c[i]), lst[i] = c[i];
sort(lst + 1, lst + m + 1);
idx = unique(lst + 1, lst + m + 1) - lst - 1;
for(int i = 1; i <= m; i++)
c[i] = lower_bound(lst + 1, lst + idx + 1, c[i]) - lst;
for(int i = n; i; i--)
for(int j = i; j <= n; j++){
for(int k = 1; k <= idx; k++)
for(int h = i; h <= j; h++)
cnt[h][k] = 0;
for(int k = 1; k <= m; k++)
for(int h = i; h <= j; h++)
if(a[k] >= i && a[k] <= h && b[k] >= h && b[k] <= j)
cnt[h][c[k]]++;
for(int h = i; h <= j; h++)
for(int k = idx; k; k--)
cnt[h][k] += cnt[h][k + 1];
for(int k = 1; k <= idx; k++)
for(int p = i; p <= j; p++)
if(g[i][p - 1][k] + g[p + 1][j][k] + lst[k] * cnt[p][k] >= f[i][j][k])
fp[i][j][k] = p, f[i][j][k] = g[i][p - 1][k] + g[p + 1][j][k] + lst[k] * cnt[p][k];
for(int k = idx; k; k--){
if(g[i][j][k + 1] > f[i][j][k])
gk[i][j][k] = gk[i][j][k + 1], g[i][j][k] = g[i][j][k + 1];
else
gk[i][j][k] = k, g[i][j][k] = f[i][j][k];
}
}
write(g[1][n][1]), enter;
dfs(1, n, 1);
for(int i = 1; i <= n; i++)
write(ans[i]), i == n ? enter: space; return 0;
}

BZOJ 4380 [POI2015]Myjnie | DP的更多相关文章

  1. @bzoj - 4380@ [POI2015] Myjnie

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

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

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

  3. bzoj4380[POI2015]Myjnie dp

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

  4. 【BZOJ】4380: [POI2015]Myjnie

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

  5. BZOJ 4380 Myjnie 区间DP

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

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

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

  7. bzoj [POI2015]Myjnie

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

  8. [POI2015]Myjnie

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

  9. bzoj 4386: [POI2015]Wycieczki

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

随机推荐

  1. 20155327 EXP8 Web基础

    20155320 EXP8 Web基础 基础问题回答 什么是表单? 表单:可以收集用户的信息和反馈意见,是网站管理者与浏览者之间沟通的桥梁. 表单由文本域.复选框.单选框.菜单.文件地址域.按钮等表单 ...

  2. 使用Gzip压缩数据,加快页面访问速度

                 在返回的json数据量大时,启用Gzip压缩,可以提高传输效率.下面为Gzip压缩对json字符串压缩并输出到页面的代码. 一.代码 /** 向浏览器输出字符串响应数据,启用 ...

  3. POJ 1860&&3259&&1062&&2253&&1125&&2240

    六道烦人的最短路(然而都是水题) 我也不准备翻译题目了(笑) 一些是最短路的变形(比如最长路,最短路中的最长边,判环),还有一些就是裸题了. 1860:找环,只需要把SPFA的松弛条件改一下即可,这里 ...

  4. 汇编 循环位移指令 ROL, 循环位移指令 ROR

    知识点:  循环位移指令 ROL  循环位移指令 ROR 一.循环位移指令 ROL ROR int i=0x77886611;//01110111100010000110011000010001 ...

  5. Linux 下的编译安装说明

    https://www.linuxidc.com/Linux/2017-02/140309.htm

  6. 移动webapp的那些令你头疼的事

    bug持续更新中... 测试浏览器 Chrome: 61.0.3163.73 Safari: 10.0(IOS 10.3.3) Github: webapp-bugs 1. IOS overflow: ...

  7. Selenium+Python自动化测试环境搭建和搭建过程遇到的问题解决

    环境搭建: 第一步:安装Python  网址:https://www.python.org/ 按照如图提示安装,并且配置环境变量(安装时候选中pip会自动安装Python的包管理工具 pip,推荐选择 ...

  8. DICOM 协议学习笔记之 How Does DICOM Work ?

    How Does DICOM Work ? DICOM有一套自己自己的模型体系,在进行具体介绍之前,首先讲解下DICOM模型: 在DICOM世界当中,所有的包括患者.检查.医学设备等都可以被视为具有不 ...

  9. 条件GAN论文简单解读

        条件GAN(Conditional Generative Adversarial Nets),原文地址为CGAN. Abstract     生成对抗网络(GAN)是最近提出的训练生成模型(g ...

  10. 利用KMP算法解决串的模式匹配问题(c++) -- 数据结构

    题目: 7-1 串的模式匹配 (30 分) 给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串 ...