题目链接

luogu P3592 [POI2015]MYJ

题解

区间dp

设f[l][r][k]表示区间l到r内最小值>=k的最大收益

枚举为k的位置p,那么包含p的区间答案全部是k

设h[i][j]表示 当前区间穿过i,且c>=j的区间数量,对i的。

然后我们可以做差分,扫一遍,递推出来

\(f[l][r][k]=max(max(f[l][p][k]+f[p+1][r][k]+h[p][k]×k,p∈[l,r]),f[l][r][k+1])\)

对于c离散化

输出方案吼啊

代码

/*
区间dp
设f[l][r][k]表示区间l到r内最小值>=k的最大收益
枚举为k的位置p,那么包含p的区间答案全部是k
设h[i][j]表示 当前区间穿过i,且c>=j的区间数量,对i的。
然后我们可以做差分,扫一遍,递推出来
f[l][r][k]=max(max(f[l][p][k]+f[p+1][r][k]+h[p][k]×k,p∈[l,r]),f[l][r][k+1])
对于c离散化
*/
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9')c = getchar();
while(c <= '9' && c >= '0')x = x * 10 + c -'0',c = getchar();
return x * f;
}
const int maxm = 4007;
const int maxn = 78;
int C[maxm], a[maxm],b[maxm],c[maxm];
int loc[maxn][maxn][maxm];
int dp[maxn][maxn][maxm],h[maxn][maxm];
int n , m , num;
void get_h(int l,int r ) {
for(int i = 1;i <= n;++ i)
for(int j = 1;j <= num;++ j) h[i][j] = 0;
for(int i = 1;i <= m;++ i)
if(l <= a[i] && r >= b[i])
++ h[a[i]][1],-- h[a[i]][c[i] + 1],-- h[b[i] + 1][1],++ h[b[i] + 1][c[i] + 1];
for(int i = l;i <= r;++ i)
for(int j = 1;j <= num;++ j)
h[i][j] += h[i - 1][j] + h[i][j - 1] - h[i - 1][j - 1];
}
int Ans[maxn];
void dfs(int l,int r,int k) {
if(r < l) return;
while(dp[l][r][k] <= dp[l][r][k + 1] && k < num) ++ k;
int Pos = loc[l][r][k];
if(Pos == 0) return ;
Ans[Pos] = C[k];
dfs(l,Pos - 1,k),dfs(Pos + 1,r,k);
}
int main() {
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;++ i)
a[i] = read(),b[i] = read(),C[i] = c[i] = read();
std::sort(C + 1,C + m + 1);
num = unique(C + 1,C + m + 1) - C - 1;
for(int i = 1;i <= m;++ i) c[i] = lower_bound(C + 1,C + num + 1,c[i]) - C;
for(int i = 1;i <= m;++ i)
if(a[i] == b[i])
for(int j = 1;j <= c[i];++ j) dp[a[i]][a[i]][j] += C[j];
for(int i = 1;i <= n;++ i)
for(int j = num - 1;j; -- j) dp[i][i][j] = std::max(dp[i][i][j],dp[i][i][j + 1]);
for(int i = 1;i <= n; ++ i)
for(int j = 0;j <= num; ++ j) loc[i][i][j] = i;
for(int k = 2;k <= n;++ k) {
for(int r, l = 1;l + k - 1 <= n;++ l) {
r = l + k - 1;
get_h(l,r); for(int i = num;i; --i) {
for(int j = l;j <= r;++ j)
if(dp[l][j - 1][i] + dp[j + 1][r][i] + h[j][i] * C[i] >= dp[l][r][i]) {
dp[l][r][i] = dp[l][j - 1][i] + dp[j + 1][r][i] + h[j][i] * C[i];
loc[l][r][i] = j;
}
if(dp[l][r][i] < dp[l][r][i + 1]) {
dp[l][r][i] = dp[l][r][i + 1];
loc[l][r][i] = loc[l][r][i + 1];
}
}
}
}
int ans = 1;
for(int i = 2;i <= num;++ i) {
if(dp[1][n][i] > dp[1][n][ans]) ans = i;
}
printf("%d\n",dp[1][n][ans]);
dfs(1,n,ans);
for(int i = 1;i <= n;++ i) printf("%d ",Ans[i]);
return 0;
}

luogu P3592 [POI2015]MYJ的更多相关文章

  1. P3592 [POI2015]MYJ

    P3592 [POI2015]MYJ 一道比较烦的区间dp.. 昨天上课讲到了这题,然后就在lg翻到了 然后调了很久很久..... 设\(f[l][r][k]\)为区间\([l,r]\)中,最小值\( ...

  2. 洛谷 P3592 [POI2015]MYJ

    题意 给定\(m\)个区间\([a_i,b_i]\)以及\(c_i\),对于一个含有\(n\)个元素的序列\(ans[]\),区间\(i\)对其的贡献为\(\min\{ans_i\}(i\in[a_i ...

  3. BZOJ 4386 Luogu P3597 [POI2015]Wycieczki (矩阵乘法)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4386 (luogu) https://www.luogu.org/pro ...

  4. BZOJ4377 Kurs szybkiego czytania \ Luogu 3589[POI2015]KUR - 数学思维题

    Solution 我又双叒叕去看题解啦$QAQ$, 真的想不到鸭 输入 $a$ 和 $n$ 互质, 所以满足 $a \times i \ mod \ n$ $(0<=i<n)$ 肯定是不重 ...

  5. Luogu 3594 [POI2015]WIL-Wilcze doły

    简单题. 考虑没有修改数字的条件的限制,我们直接用双指针扫描就可以计算出答案了. 然后考虑加入修改数字的条件,只要用单调队列维护出当前两个指针表示的区间中长度为$d$的一段区间的最大值,用总和减掉这个 ...

  6. Luogu 3586 [POI2015]LOG

    考虑离散化后开权值线段树. 设序列中不小于$s$的数有$cnt$个,小于$s$的数的和为$sum$. 那么操作Z能成功的充要条件是$sum \geq (c - cnt) * s$. 如果序列中不小于$ ...

  7. DP没入门就入土

    写在前面 记录最近刷的DP题 以及 打死都不可能想到状态设计DP系列 汇总 洛谷 P6082 [JSOI2015]salesman 树形\(\texttt{DP}\) + 优先队列 比较容易看出来这是 ...

  8. 【做题记录】DP 杂题

    P2577 [ZJOI2004]午餐 $\texttt{solution}$ 想到贪心: 吃饭慢的先打饭节约时间, 所以先将人按吃饭时间从大到小排序. 状态: \(f[i][j]\) 表示前 \(i\ ...

  9. Luogu P3783 [SDOI2017]天才黑客

    题目大意 一道码量直逼猪国杀的图论+数据结构题.我猪国杀也就一百来行 首先我们要看懂鬼畜的题意,发现其实就是在一个带权有向图上,每条边有一个字符串信息.让你找一个点出发到其它点的最短路径.听起来很简单 ...

随机推荐

  1. 技术分享:如何在PowerShell脚本中嵌入EXE文件

    技术分享:如何在PowerShell脚本中嵌入EXE文件 我在尝试解决一个问题,即在客户端攻击中只使用纯 PowerShell 脚本作为攻击负荷.使用 PowerShell 运行恶意代码具有很多优点, ...

  2. avalonJS-源码阅读(二)

    上一篇文章讲述的avalon刷页面所用到的几个函数.这篇则是主要讲avalon对刷DOM刷出来的avalon自定义属性如何处理的. 目录[-] avalon页面处理(2) 数据结构 解析avalon标 ...

  3. Vue起步

    Vue起步 Vue.js是什么 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式javascript框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用. ...

  4. python 之datetime库学习

    # -*- coding:utf-8 -*- import refrom datetime import datetime, timezone, timedelta def rec_time():   ...

  5. 形参前的&&啥意思?

    C++2011标准的 右值引用 语法 去搜索“c++11右值引用” 右值引用,当传入临时对象时可以避免一次拷贝. 右值引用.举个例子 C/C++ code   ? 1 2 3 4 5 6 7 8 // ...

  6. SpringCloud常用注解

    一 @EnableDiscoveryClient,@EnableEurekaClient的区别 SpringCLoud中的“Discovery Service”有多种实现,比如:eureka, con ...

  7. P2471 [SCOI2007]降雨量

    Description 我们常常会说这样的话:"X年是自Y年以来降雨量最多的".它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年.例如2 ...

  8. 洛谷P2016战略游戏

    传送门啦 战略游戏这个题和保安站岗很像,这个题更简单,这个题求的是士兵人数,而保安站岗需要求最优价值. 定义状态$ f[u][0/1] $ 表示 $ u $ 这个节点不放/放士兵 根据题意,如果当前节 ...

  9. 洛谷P1411 砝码称重

    传送门啦 这个题总体思路就是先搜索在 $ dp $ void dfs(int keep,int now){ //使用 放弃 if(now > m) return; //已经放弃超过m个了,就退出 ...

  10. HDU 3360 National Treasures(最小点覆盖)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3360 题目大意: 在一个n*m的格子中,每个格子有一个数值,-1表示空,其余表示财宝.每个财宝的数值转 ...