Description

期末考试结束了,班主任L老师要将成绩单分发到每位同学手中。L老师共有n份成绩单,按照编号从1到n的顺序叠
放在桌子上,其中编号为i的成绩单分数为w_i。成绩单是按照批次发放的。发放成绩单时,L老师会从当前的一叠
成绩单中抽取连续的一段,让这些同学来领取自己的成绩单。当这批同学领取完毕后,L老师再从剩余的成绩单中
抽取连续的一段,供下一批同学领取。经过若干批次的领取后,成绩单将被全部发放到同学手中。然而,分发成绩
单是一件令人头痛的事情,一方面要照顾同学们的心理情绪,不能让分数相差太远的同学在同一批领取成绩单;另
一方面要考虑时间成本,尽量减少领取成绩单的批次数。对于一个分发成绩单的方案,我们定义其代价为:
其中,k是方案中分发成绩单的批次数,对于第i批分发的成绩单,〖max〗_i是最高分数,〖min〗_i是最低分数。
a,b是给定的评估参数。现在,请你帮助L老师找到代价最小的分发成绩单的方案,并将这个最小的代价告诉L老师
。当然,分发成绩单的批次数k是由你决定的。

Input

第一行包含一个正整数n,表示成绩单的数量。
第二行包含两个非负整数a,b,表示给定的评估参数。
第三行包含n个正整数w_i,表示第i张成绩单上的分数。

Output

仅一个正整数,表示最小的代价是多少。

这是一个非常神仙的区间 DP.
令 $g[l][r][i][j]$ 表示将区间 $[l,r]$ 删至所有权值都在 $[i,j]$ 之内的最小代价.
令 $f[l,r]$ 表示将 $[l,r]$ 区间全部删掉的最小代价.
上一次的更新更新完了 $r-1$,所以说 $g[l][r-1]$ 都是可以用于更新 $g[l][r]$ 的.
考虑新加入 $r$, 那么要分成两种情况:
1. 没有被删掉,即和权值在 $[i,j]$ 之内的连续子序列构成了一个新的序列.
2. 被删掉,即 $r$ 不会影响到任何决策.

写成状态转移:
1. $g[l][r-1][i][j]\Rightarrow g[l][r][min(i,w[r])][max(j,w[r])]$
2. $g[l][k][i][j]+f[k+1][r]\Rightarrow g[l][r][i][j]$

由于这是区间 $DP$,所以区间长度更小的已经被解决掉了,所以转移是完全合法的.
动态规划的一个小窍门就是每次可以指定什么什么东西,比如这次就指定了每次只加入右端点.

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 52
#define setIO(s) freopen(s".in", "r" , stdin)
int w[N], v[N], f[N][N], g[N][N][N][N];
inline void getmin(int &a, int b)
{
if(b < a) a = b;
}
int main()
{
// setIO("input");
int n, A, B, i, j, len;
scanf("%d%d%d", &n , &A, &B), memset(f, 0x3f, sizeof(f)), memset(g, 0x3f, sizeof(g));
for(i = 1; i <= n ; ++ i) scanf("%d", &w[i]), v[i] = w[i];
std :: sort(v + 1, v + 1 + n);
for(i = 1; i <= n ; ++ i)
{
w[i] = std :: lower_bound(v + 1, v + 1 + n, w[i]) - v;
f[i][i] = A, g[i][i][w[i]][w[i]] = 0;
}
for(len = 2; len <= n ; ++ len)
{
int l, r, k;
for(l = 1; l + len - 1 <= n ; ++ l)
{
r = l + len - 1;
for(i = 1; i <= n ; ++ i)
{
for(j = i; j <= n ; ++ j)
getmin( g[l][r][std :: min(i, w[r])][std :: max(j, w[r])], g[l][r - 1][i][j]);
}
for(k = l; k < r ; ++ k)
{
for(i = 1; i <= n ; ++ i)
for(j = i; j <= n ; ++ j)
getmin(g[l][r][i][j], g[l][k][i][j] + f[k + 1][r]);
}
for(i = 1; i <= n ; ++ i)
{
for(j = i; j <= n ; ++ j)
getmin(f[l][r], g[l][r][i][j] + A + B * (v[j] - v[i]) * (v[j] - v[i]));
}
}
}
printf("%d\n", f[1][n]);
return 0;
}

  

BZOJ 4897: [Thu Summer Camp2016]成绩单 动态规划的更多相关文章

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

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

  2. BZOJ4897: [Thu Summer Camp2016]成绩单【DP of DP】

    Description 期末考试结束了,班主任L老师要将成绩单分发到每位同学手中.L老师共有n份成绩单,按照编号从1到n的顺序叠 放在桌子上,其中编号为i的成绩单分数为w_i.成绩单是按照批次发放的. ...

  3. 【bzoj4897】[Thu Summer Camp2016]成绩单 区间dp

    题目描述 给你一个数列,每次你可以选择连续的一段,付出 $a+b\times 极差^2$ 的代价将其删去,剩余部分拼到一起成为新的数列继续进行此操作.求将原序列全部删去需要的最小总代价是多少. 输入 ...

  4. bzoj4897 [Thu Summer Camp2016]成绩单

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4897 [题解] 第一次看这题想的是f[l,r]的区间dp发现仅记录这两个好像不能转移啊 会出 ...

  5. BZOJ4897 [Thu Summer Camp2016]成绩单 【dp】

    题目链接 BZOJ4897 题解 发现我们付出的代价与区间长度无关,而与区间权值范围有关 离散化一下权值 我们设\(f[l][r][x][y]\)表示区间\([l,r]\)消到只剩权值在\([x,y] ...

  6. BZOJ 4896: [Thu Summer Camp2016]补退选

    trie树+vector+二分 别忘了abs(ans) #include<cstdio> #include<algorithm> #include<vector> ...

  7. BZOJ 4896 :[Thu Summer Camp2016]补退选 Trie树+Vector

    4896: [Thu Summer Camp2016]补退选 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 315  Solved: 97[Submi ...

  8. 【BZOJ4896】[Thu Summer Camp2016]补退选 Trie树

    [BZOJ4896][Thu Summer Camp2016]补退选 Description X是T大的一名老师,每年他都要教授许多学生基础的C++知识.在T大,每个学生在每学期的开学前都需要选课,每 ...

  9. bzoj 3522 / 4543 [POI 2014] Hotel - 动态规划 - 长链剖分

    题目传送门 bzoj 3522 需要root权限的传送点 bzoj 4543 快速的传送点 慢速的传送点 题目大意 给定一棵树,问有多少个无序三元组$(x, y, z)$使得这三个不同点在树上两两距离 ...

随机推荐

  1. 【计算机视觉】【图像处理】【VS开发】【Qt开发】opencv之深拷贝及浅拷贝,IplImage装换为Mat

    原文:opencv之深拷贝及浅拷贝,IplImage装换为Mat  一.(1) 浅拷贝: Mat B; B = image // 第一种方式 Mat C(image); // 第二种方式 这两种方式称 ...

  2. Windows 下 C/C++ 多线程编程入门参考范例

    #include <windows.h> #include <iostream> using namespace std; DWORD WINAPI myThread(LPVO ...

  3. CSS基本样式-文本属性

    字体属性 文本属性呢,自我认为就是写文档的一些格式属性,例如:字体颜色,字体加粗,字体大小,字体类型等,而且我们在输出测试用例报告的时候也可以用到这些属性,对测试报告进行优化. <html> ...

  4. 使用lombok.Data编译时无法找到get/set方法

    我的IDEA版本是2019.2 在使用IDEA创建了一个SpringBoot项目,其中一个实体类使用了@Data注解,但是在Service中调用的时候找不到get/set方法. 检查步骤: 1.在St ...

  5. BZOJ 4857 反质数序列

    题面 奇数+奇数一定不是质数(1+1除外),偶数+偶数一定不是质数,质数只可能出现在偶数+奇数中 把所有的点排成两列,权值为奇数的点在左边,权值为偶数的在右边 如果左边的点x+右边的点y是质数,我们就 ...

  6. c语言小技巧:C语言学习笔记之位运算求余

    我们都知道,求一个数被另一个数整除的余数,可以用求余运算符”%“,但是,如果不 允许使用求余运算符,又该怎么办呢?下面介绍一种方法,是通过位运算来求余,但是注 意:该方法只对除数是2的N次方幂时才有效 ...

  7. kafka 教程(三)-远程访问

    远程连接 kafka 配置 默认的 kafka 配置是无法远程访问的,解决该问题有几个方案. 方案1 advertised.listeners=PLAINTEXT://IP:9092 注意必须是 ip ...

  8. 使用Tomcat、JNDI与ActiveMQ实现JMS消息通信服务

    前言 之所以使用JNDI 是出于通用性考虑,该例子使用JMS规范提供的通用接口,没有使用具体JMS提供者的接口,这样可以保证我们编写的程序适用于任何一种JMS实现(ActiveMQ.HornetQ等) ...

  9. day 03 int bool str (索引,切片) for 循环

    基础数类型总览 10203 123 3340 int +- * / 等等 '今天吃了没?' str 存储少量的数据,+ *int 切片, 其他操作方法 True False bool 判断真假 [12 ...

  10. 093、如何用Graylog 管理日志? (2019-05-17 周五)

    参考https://www.cnblogs.com/CloudMan6/p/7821817.html   上节我们已经部署好了 Graylog ,现在学习如何使用他来管理日志.   首先运行测试容器, ...