BZOJ 4380 Myjnie 区间DP
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
1 4 7
3 7 13
5 6 20
6 7 1
1 2 5
Sample Output
5 5 13 13 20 20 13
HINT
Source
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的更多相关文章
- 【BZOJ-4380】Myjnie 区间DP
4380: [POI2015]Myjnie Time Limit: 40 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 162 Solved: ...
- 【BZOJ4380】[POI2015]Myjnie 区间DP
[BZOJ4380][POI2015]Myjnie Description 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i].有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[ ...
- [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 ...
- 【BZOJ 4380】4380: [POI2015]Myjnie (区间DP)
4380: [POI2015]Myjnie Description 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i].有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗 ...
- BZOJ 4380 [POI2015]Myjnie | DP
链接 BZOJ 4380 题面 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i]. 有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗车店,且会选择这些店中最便宜的一个 ...
- BZOJ.4897.[Thu Summer Camp2016]成绩单(区间DP)
BZOJ 显然是个区间DP.令\(f[l][r]\)表示全部消掉区间\([l,r]\)的最小花费. 因为是可以通过删掉若干子串来删子序列的,所以并不好直接转移.而花费只与最大最小值有关,所以再令\(g ...
- [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 ...
- [BZOJ 1260][CQOI2007]涂色paint 题解(区间DP)
[BZOJ 1260][CQOI2007]涂色paint Description 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为 ...
- [BZOJ 1032][JSOI 2007]祖玛 题解(区间DP)
[BZOJ 1032][JSOI 2007]祖玛 Description https://www.lydsy.com/JudgeOnline/problem.php?id=1032 Solution ...
随机推荐
- 【工具记录】Linux口令破解
1.基础知识 /etc/passwd:记录着用户的基本属性,所有用户可读 字段含义如下: 用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell eg: root:x:0:0:root ...
- c# 通过Windows服务启动外部程序
1. 新建一个Windows服务应用程序 创建项目——>Visual C# 左侧的"+"——>Windows ——>Windows 服务(右侧模板)——>输 ...
- asp.net mvc发送邮件
参考文献: 第一篇:http://www.cnblogs.com/qinpengming/archive/2011/06/08/2075040.html 第二篇:http://www.cnblogs. ...
- Git如何设置多个用户
前言 由于我们在使用GitHub时,通常不希望带有公司信息,所以需要独立的Git账户来提交练习代码,本文记录一下如何配置多个Git账户并创建公钥 正文 1.首先进入~/.ssh文件夹 2.然后创建一个 ...
- 15 Defer, Panic, and Recover
Defer, Panic, and Recover 4 August 2010 Go has the usual mechanisms for control flow: if, for, switc ...
- SpringCloud常用注解
一 @EnableDiscoveryClient,@EnableEurekaClient的区别 SpringCLoud中的“Discovery Service”有多种实现,比如:eureka, con ...
- Animate.css 前端动画开发教程
1.首先下载animate.css文件: 2.打开动画预览地址选择想要的动画,地址:https://daneden.github.io/animate.css/ ,选择好后记住动画的名字在你下载的a ...
- 关闭linux退格键和vi发出的嘟嘟声
以root用户登录,然后请安下面方法进行操作: 在命令行下执行:echo "rmmod pcspkr" >> /etc/rc.d/rc.local
- Effective STL 学习笔记 Item 18: 慎用 vector<bool>
vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...
- JS实现点击图片,在浏览器中查看。
工作中遇到要实现点击图片查看的功能,从网上找了一段js代码,可以用. <img src="/pic/${pictureCertificate}" alt="凭证&q ...