传送门

区间dp好题。


f[i][j][k]f[i][j][k]f[i][j][k]表示区间[i,j][i,j][i,j]最小值为kkk时的最大贡献。

然后可以枚举端点转移。

当时口胡到这儿就不会了。

于是细节请教了DZYODZYODZYO学长。

大概就是预处理出区间[l,r][l,r][l,r]中大于等于valvalval的有几个数来优化转移。

每个fff数组中记录:

当前的最优值。

k以及其后缀的最优值的最优值。

当前区间最优值取得的端点。

以及对应的数。

代码(跟DZYODZYODZYO的差不多巨佬勿喷):

#include<bits/stdc++.h>
#define N 52
#define M 4005
#define fi first
#define se second
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef pair<int,int> pii;
pii S[M];
int n,m,cnt[N][N][M],rk[M],l[M],r[M],c[M],tot=0;
struct node{pii val;int pos,pre;}f[N][N][M];
node dfs(int l,int r,int w){
	if(l>r||w>tot)return (node){make_pair(0,0),0,0};
	if(~f[l][r][w].val.fi)return f[l][r][w];
	f[l][r][w].val.fi=0;
	node tmp=dfs(l,r,w+1);
	if(l==r){
		f[l][l][w].val.fi=cnt[l][l][w]*rk[w];
		f[l][l][w].val.se=max(f[l][l][w].val.fi,tmp.val.se);
		f[l][l][w].pre=(w!=tot&&tmp.val.se>f[l][l][w].val.fi)?tmp.pre:w;
		f[l][l][w].pos=l;
		return f[l][l][w];
	}
	int pos,mx=0;
	for(int mid=l,mxtmp=0;mid<=r;++mid){
		mxtmp=dfs(l,mid-1,w).val.se+rk[w]*(cnt[l][r][w]-cnt[l][mid-1][w]-cnt[mid+1][r][w])+dfs(mid+1,r,w).val.se;
		if(mxtmp>=mx)mx=mxtmp,pos=mid;
	}
	f[l][r][w].val.fi=mx;
	f[l][r][w].val.se=max(mx,tmp.val.se);
	f[l][r][w].pos=pos;
	f[l][r][w].pre=(w!=tot&&tmp.val.se>mx)?tmp.pre:w;
	return f[l][r][w];
}
inline void print(int l,int r,int val){
    int pre=f[l][f[l][r][val].pos-1][val].pre,suf=f[f[l][r][val].pos+1][r][val].pre;
    if(l<f[l][r][val].pos&&pre)print(l,f[l][r][val].pos-1,pre);
    printf("%d ",rk[val]);
    if(r>f[l][r][val].pos&&suf)print(f[l][r][val].pos+1,r,suf);
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=m;++i)l[i]=read(),r[i]=read(),c[i]=read(),S[i]=make_pair(c[i],i);
	sort(S+1,S+m+1);
	for(int i=1;i<=m;++i){
		if(i==1||(S[i].fi^S[i-1].fi))++tot;
		rk[tot]=c[S[i].se],c[S[i].se]=tot;
	}
	for(int i=1;i<=n;++i)for(int j=i;j<=n;++j)for(int k=1;k<=tot;++k)f[i][j][k].val.fi=-1;
	for(int i=1;i<=m;++i)for(int j=1;j<=l[i];++j)for(int k=r[i];k<=n;++k)++cnt[j][k][c[i]];
	for(int i=1;i<=n;++i)for(int j=i;j<=n;++j)for(int k=tot;k;--k)cnt[i][j][k]+=cnt[i][j][k+1];
	int Pos,mx=0;
	for(int i=tot;i;--i){
		node tmp=dfs(1,n,i);
		if(tmp.val.fi>mx)Pos=i,mx=tmp.val.fi;
	}
	printf("%d\n",mx);
	print(1,n,Pos);
	return 0;
}

2018.10.22 bzoj4380: [POI2015]Myjnie(区间dp)的更多相关文章

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

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

  2. 【BZOJ-4380】Myjnie 区间DP

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

  3. 2018.10.23 hdu2476String painter(区间dp)

    传送门 一道挺妙的区间dp. 我们先用区间dp求出第一个串为空串时的最小代价. 然后再加入原本的字符更新答案就行了. 代码: #include<bits/stdc++.h> using n ...

  4. 2018.10.23 hdu4745Two Rabbits(区间dp)

    传送门 区间dp经典题目. 首先断环为链. 然后题目相当于就是在找最大的回文子序列. 注意两个位置重合的时候相当于范围是n,不重合时范围是n-1. 代码: #include<bits/stdc+ ...

  5. 2018.10.22 bzoj1742: Grazing on the Run 边跑边吃草(区间dp)

    传送门 区间dp入门题. 可以想到当前吃掉的草一定是一个区间(因为经过的草一定会吃掉). 然后最后一定会停在左端点或者右端点. f[i][j][0/1]f[i][j][0/1]f[i][j][0/1] ...

  6. bzoj4380[POI2015]Myjnie dp

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

  7. BZOJ 4380 Myjnie 区间DP

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

  8. 2018.10.22 bzoj1009: [HNOI2008]GT考试(kmp+矩阵快速幂优化dp)

    传送门 f[i][j]f[i][j]f[i][j]表示从状态"匹配了前i位"转移到"匹配了前j位"的方案数. 这个东西单次是可以通过跳kmp的fail数组得到的 ...

  9. NOIP模拟赛-2018.10.22

    模拟赛 今天第一节课是历史,当然是不可能上的,一来到机房发现今天高二考试... 老师说以后可能还要给高一考...那还不如现在跟着做好了,毕竟在学长学姐中垫底显得没那么丢人 这套题风格挺奇怪的...为什 ...

随机推荐

  1. 多媒体基础知识之PCM数据

    1.什么是PCM音频数据 PCM(Pulse Code Modulation)也被称为脉冲编码调制.PCM音频数据是未经压缩的音频采样数据裸流,它是由模拟信号经过采样.量化.编码转换成的标准的数字音频 ...

  2. python 在内存中处理tar.bz2文件

    如果tar.bz2文件是通过网络进行下载,那么可以直接在内存进行解压后读取文件内容,不用将文件缓存到本地然后解压再进行读取,可以节省IO. 处理经过gzip压缩的tar文件的方法见:https://s ...

  3. 漫画描述HDFS工作原理

    作者不详,内容浅显易懂,特拿来与大家分享.

  4. liblas 1.8.1编译安装

    liblas https://github.com/libLAS/libLAS/issues/102 https://liblas.org/start.html 源码 https://github.c ...

  5. 机房servlet过滤器

    1.源代码 loginform.html <html> <head> <title>使用过滤器改变请求编码</title> <meta http- ...

  6. 新手C#SQL Server使用记录2018.08.10

    主键(PrimaryKey):主键就是每个数据行(记录)的唯一标识,不会有重复值的列(字段)才能当做主键.一个表可以没有主键,但是这样会很难处理表,因此一般情况表都要设置主键. 主键有两张选用策略,分 ...

  7. zabbix超级乱码解决问题

    个人而言,网上那些方法并不顶什么用,研究了一番总结出了自己的一个方法. 像这种,出现了严重乱码,也不是像网上说的那样把楷体复制过去就好.事实证明我复制过去好多次了,然而并没有什么用. 下面是我自己总结 ...

  8. Cookie进行会话管理

    一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...

  9. xpath的层级与逻辑定位

    xpath的层级与逻辑定位: 之前我们是通过class和id,name,如果我们所需要的元素没有class,id,name这样的元素,怎么定位呢 1.在不使用xpath情况下:元素没有属性值得时候怎么 ...

  10. 用Python写单向链表和双向链表

    链表是一种数据结构,链表在循环遍历的时候效率不高,但是在插入和删除时优势比较大. 链表由一个个节点组成. 单向链表的节点分为两个部分:存储的对象和对下一个节点的引用.注意是指向下一个节点. 而双向链表 ...