4380: [POI2015]Myjnie

Time Limit: 40 Sec  Memory Limit: 256 MBSec  Special Judge
Submit: 162  Solved: 82
[Submit][Status][Discuss]

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],c[i](1<=a[i]<=b[i]<=n,1<=c[i]<=500000)

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

HINT

Source

鸣谢Claris

Solution

这个区间DP的思路十分神奇。

设G[l][r][i]为区间[l, r]中最小值为k的最优值,F[l][r][i] = max{G[l][r][j]} (j >= i)。

转移:F[l][r][i] = max{F[l][k-1]+F[k+1][r]+c[i]*cnt[k][i]} (cnt[k][i]就是指c[j]>=i且在区间[l,r]中且跨越点k的个数)

对于方案的记录,我们只需要在转移的时候记录,最后再从最优解开始dfs就可以了。

但是千万要注意的是,所有合法的情况初始化为-INF。不这样做的话,就构不出方案,把f转为0的时候就把方案给记录下来了。

Code

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm> using namespace std; #define FIO "a"
#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define DWN(i, a, b) for (int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define mset(a, b) memset(a, b, sizeof(a))
const int maxn = , maxm = , INF = 0x3fffffff;
int n, m, a[maxm], b[maxm], c[maxm];
int t[maxm], t_cnt;
int f[maxn][maxn][maxm], cnt[maxn][maxm], from[maxn][maxn][maxn], las[maxn][maxn][maxn];
int ans[maxn]; void dfs(int l, int r, int k)
{
if (l > r) return ;
ans[from[l][r][k]] = t[las[l][r][k]];
dfs(l, from[l][r][k]-, las[l][r][k]);
dfs(from[l][r][k]+, r, las[l][r][k]);
} int main()
{
// freopen(FIO ".in", "r", stdin);
// freopen(FIO ".out", "w", stdout);
scanf("%d %d", &n, &m);
t_cnt = ;
REP(i, , m) scanf("%d %d %d", &a[i], &b[i], &c[i]), t[++t_cnt] = c[i];
sort(t+, t+t_cnt+);
int temp = t_cnt, x; t_cnt = ;
REP(i, , temp) if (t[i] != t[i-]) t[++t_cnt] = t[i];
REP(i, , m) c[i] = lower_bound(t+, t+t_cnt+, c[i])-t;
REP(i, , n) REP(j, i, n) REP(k, , m) f[i][j][k] = -INF;
REP(len, , n)
REP(l, , n-len+)
{
int r = l+len-;
REP(i, l, r) REP(j, , m) cnt[i][j] = ;
REP(i, , m)
if (a[i] >= l && b[i] <= r)
REP(j, a[i], b[i]) cnt[j][c[i]] ++;
REP(i, l, r) DWN(j, m-, ) cnt[i][j] += cnt[i][j+];
REP(k, l, r)
REP(i, , m)
if (f[l][k-][i]+f[k+][r][i]+t[i]*cnt[k][i] > f[l][r][i])
f[l][r][i] = f[l][k-][i]+f[k+][r][i]+t[i]*cnt[k][i],
from[l][r][i] = k, las[l][r][i] = i;
DWN(i, m-, )
if (f[l][r][i] < f[l][r][i+])
f[l][r][i] = f[l][r][i+],
from[l][r][i] = from[l][r][i+], las[l][r][i] = las[l][r][i+];
}
printf("%d\n", f[][n][]);
dfs(, n, );
REP(i, , n) printf("%d%c", ans[i], i == n ? '\n' : ' ');
return ;
}

BZOJ 4380 Myjnie 区间DP的更多相关文章

  1. 【BZOJ-4380】Myjnie 区间DP

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

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

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

  3. [bzoj] 1068 压缩 || 区间dp

    原题 f[i][j][0/1]表示i-1处有一个M,i到j压缩后的长度,0/1表示i到j中有没有m. 初始为j-i+1 f[i][j][0]=min(f[i][j][0],f[i][k][0]+j-k ...

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

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

  5. BZOJ 4380 [POI2015]Myjnie | DP

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

  6. BZOJ.4897.[Thu Summer Camp2016]成绩单(区间DP)

    BZOJ 显然是个区间DP.令\(f[l][r]\)表示全部消掉区间\([l,r]\)的最小花费. 因为是可以通过删掉若干子串来删子序列的,所以并不好直接转移.而花费只与最大最小值有关,所以再令\(g ...

  7. [BZOJ 1652][USACO 06FEB]Treats for the Cows 题解(区间DP)

    [BZOJ 1652][USACO 06FEB]Treats for the Cows Description FJ has purchased N (1 <= N <= 2000) yu ...

  8. [BZOJ 1260][CQOI2007]涂色paint 题解(区间DP)

    [BZOJ 1260][CQOI2007]涂色paint Description 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为 ...

  9. [BZOJ 1032][JSOI 2007]祖玛 题解(区间DP)

    [BZOJ 1032][JSOI 2007]祖玛 Description https://www.lydsy.com/JudgeOnline/problem.php?id=1032 Solution ...

随机推荐

  1. imperva-代理安装

    首先创建网关上面的监听端口

  2. idea git revert 究竟做了啥

    git里面实现撤销commit 这个据我目前所知,有至少4个途径可以做到 1.git reset 2.git revert 3.git rm –cached 4.git checkout 这个可以参考 ...

  3. redis从入门到放弃 -> 部署方案

    单点部署方案 环境准备: [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@ ...

  4. os.path.isdir(path)异常

    Window 10家庭中文版,Python 3.6.4, 当一个路径以多个斜杠(/)或反斜杠字符(\\)结尾时,os.path.isdir(path)函数仍然将它们判断为目录: >>> ...

  5. Python解决八皇后问题的代码【解读】

    八皇后问题 来自于西方象棋(现在叫 国际象棋,英文chess),详情可见百度百科. 在西方象棋中,有一种叫做皇后的棋子,在棋盘上,如果双方的皇后在同一行.同一列或同一斜线上,就会互相攻击. 八皇后问题 ...

  6. supervisor的安装和配置

    1. 安装 yum install supervisor 2.配置 [unix_http_server] file=/tmp/supervisor.sock ;UNIX socket 文件,super ...

  7. HDU 1068 Girls and Boys(最大独立集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1068 题目大意:有n个人,一些人认识另外一些人,选取一个集合,使得集合里的每个人都互相不认识,求该集合 ...

  8. CF529B 【Group Photo 2 (online mirror version)】

    贪心枚举最后方案中最大的h,设为maxh若某个人i的wi与hi均大于maxh,则此方案不可行若某个人恰有一个属性大于maxh,则可确定他是否换属性剩下的人按wi-hi从大到小排序后贪心选择O(nlog ...

  9. 教您如何进行SQL跨表更新

    SQL跨表更新数据是在使用SQL数据库中比较常用的,下面就将为您详细介绍SQL跨表更新数据的步骤,希望对您学习SQL跨表更新数据有所启迪. 原始数据如下,首先是表结构 A_dept的初始数据 A_em ...

  10. 2016-2017-2 20155309南皓芯《java程序设计》第九周学习总结

    教材内容介绍 一 JDBC简介 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无须接触底层数据库驱动程序的差异性 JDBC标准分为两个部分:J ...