题目:https://loj.ac/problem/2292

直接 DP 很难做,主要是有那种 “一个区间内部有很多个别的区间” 的情况。

自己想了一番枚举 max-min 的最大限制,然后在该基础上最小化区间个数之类的。还是不会。

看了题解才会。

考虑再设一个 dp 数组来辅助表示那种麻烦的情况。

值可以离散化!又因为代价与值有关,可以考虑把值放进角标里。

令 f[ i ][ j ] 表示把 [ i , j ] 全取完的最小代价,g[ i ][ j ][ l ][ r ] 表示把 [ i , j ] 取得只剩下值在 [ l , r ] 之间的最小代价。

g[ i ][ j ][ l ][ r ] 转移时讨论一下 j 是否留下。若留下,则从 g[ i ][ j-1 ][ l ][ r ] 转移,否则枚举和 j 一起删掉的区间,从 g[ i ][ k-1 ][ l ][ r ] + f[ k ][ j ] 转移。

然后 f[ i ][ j ] 就是各种 g[ i ][ j ][ l ][ r ] 再加上把值在 [ l , r ] 的数一次取完的代价。

这种设状态为 “做到剩下特定元素” 的思想很好。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
const int N=,INF=;
int n,m,A,B,a[N],tp[N],f[N][N],g[N][N][N][N];
int Sqr(int x){return x*x;}
void cz(int &u,int v){if(v<u)u=v;}
int main()
{
scanf("%d%d%d",&n,&A,&B);
for(int i=;i<=n;i++)scanf("%d",&a[i]),tp[i]=a[i];
sort(tp+,tp+n+); m=unique(tp+,tp+n+)-tp-;
for(int i=;i<=n;i++)a[i]=lower_bound(tp+,tp+m+,a[i])-tp;
memset(g,0x3f,sizeof g);
for(int i=;i<=n;i++)
{
f[i][i]=A;
for(int l=;l<=m;l++)
for(int r=l;r<=m;r++)
{
if(a[i]>=l&&a[i]<=r)g[i][i][l][r]=;
else g[i][i][l][r]=A;
}
}
for(int d=;d<n;d++)
for(int i=;i+d<=n;i++)
{
int j=i+d; int mx=,mn=INF;
for(int k=i;k<=j;k++)
mx=Mx(mx,a[k]),mn=Mn(mn,a[k]);
f[i][j]=A+B*Sqr(tp[mx]-tp[mn]);
for(int l=;l<=m;l++)
for(int r=l;r<=m;r++)
{
if(a[j]>=l&&a[j]<=r)
cz(g[i][j][l][r],g[i][j-][l][r]);
for(int k=i+;k<=j;k++)
cz(g[i][j][l][r],g[i][k-][l][r]+f[k][j]);
cz(f[i][j],g[i][j][l][r]+A+B*Sqr(tp[r]-tp[l]));
}
}
printf("%d\n",f[][n]);
return ;
}

LOJ 2292 「THUSC 2016」成绩单——区间DP的更多相关文章

  1. loj 2292「THUSC 2016」成绩单

    loj 看着就很区间dp,所以考虑求\(f_{i,j}\)表示区间\([i,j]\)的答案.注意到贡献答案的方式是每次选一个连续段,拿走后剩下的段拼起来继续段,所以转移就考虑从最后一次选的方法转移过来 ...

  2. 2018.10.27 loj#2292. 「THUSC 2016」成绩单(区间dp)

    传送门 g[i][j][k][l]g[i][j][k][l]g[i][j][k][l]表示将区间l,rl,rl,r变成最小值等于kkk,最大值等于lll时的花费的最优值. f[i][j]f[i][j] ...

  3. 【LOJ】#2292. 「THUSC 2016」成绩单

    题解 神仙dp啊><(也有可能是我菜) 我们发现,想要拿一段区间的话,只和这个区间的最大值和最小值有关系,那么我们考虑,如果一个区间[l,r]我们拿走了一些数后,使它的最小值是a,最大值是 ...

  4. 「THUSC 2016」成绩单 & 方块消除 (区间dp)

    成绩单 $f[l][r][mi][mx]$表示从l到r发到还没发的部分的最小值为mi最大值为mx时的最小代价. $f[l][r][0][0]$表示从l到r全部发完的代价. 自己写的无脑dp,枚举中转点 ...

  5. LOJ 2991 「THUSC 2016」补退选——trie+线段树合并或vector

    题目:https://loj.ac/problem/2291 想了线段树合并的做法.就是用线段树维护 trie 的每个点在各种时间的操作. 然后线段树合并一番,线段树维护前缀最大值,就是维护最大子段和 ...

  6. loj2292 「THUSC 2016」成绩单

    ref 我是傻逼,我啥也不会,这是我抄的. #include <iostream> #include <cstring> #include <cstdio> usi ...

  7. 【LOJ】#2291. 「THUSC 2016」补退选

    题解 在trie树上开vector记录一下这个前缀出现次数第一次达到某个值的下标,以及记录一下现在这个前缀有多少个 为什么thusc有那么水的题--是为了防我这种cai ji爆零么= = 代码 #in ...

  8. loj2291 「THUSC 2016」补退选

    ref pkusc 快到了,做点 thusc 的题涨涨 rp-- #include <iostream> #include <cstring> #include <cst ...

  9. LOJ#2799. 「CCC 2016」生命之环

    题意 给你一个 \(n\) 个 \(\rm 01\) 组成的环,每次操作之后每个位置为1当且仅当他的左右恰好有1个1.输出进行 \(T\) 次操作之后的环. \(n\leq 10^5, T\leq 1 ...

随机推荐

  1. 使用Wscript/cscript调用VB脚本

    ●强制用Wscript.exe执行 SET Wshell=CreateObject("Wscript.Shell") if lcase(right(Wscript.fullName ...

  2. Python自学:第二章 注释

    #向大家问好 print("Hello Python People") 输出为 Hello Python People

  3. LeetCode--016--最接近的三数之和(java)

    给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案. 例如,给定数 ...

  4. 在Visual Studio 2017中安装bower

    在项目目录下添加一个文件.bowerrc { "directory": "wwwroot/lib" } JS包默认安装到webroot的lib文件夹,可以通过. ...

  5. Hive入门学习

    Hive学习之路 (一)Hive初识 目录 Hive 简介 什么是Hive 为什么使用 Hive Hive 特点 Hive 和 RDBMS 的对比 Hive的架构 1.用户接口: shell/CLI, ...

  6. coursera-斯坦福-机器学习-吴恩达-笔记week3

    1 逻辑回归 1. classification 分类 eg:垃圾邮件分类.交易是否是欺诈.肿瘤类别.分类的结果是离散值. 2. sigmoid函数 使用线性方法来判断分类问题,会出现上图中的问题,需 ...

  7. 【转载】如何将本地文件上传到github托管

    转自:http://www.cnblogs.com/babywin/p/6073124.html 清楚明白.  

  8. 蒙特·卡罗方法(Monte Carlo method)

    蒙特·卡罗方法(Monte Carlo method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法.是 ...

  9. javascript 一些特殊的写法

    数组+数组: ["f", "o", "o"]+[] 执行结果:"f,o,o" ["f", " ...

  10. 关于规范NOIP试题管理办法的通知

    由CCF主办的NOIP赛事举行在即,保密起见,现将有关规定发给各省赛区组织单位. 1.NOI各省组织单位负责试题保密工作. 2.NOIP初赛试卷为纸质版,复赛试卷为电子版. 3.在初赛进行中,如有选手 ...