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

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

Sample Input

10

3 1

7 10 9 10 6 7 10 7 1 2

Sample Output

15

【样例数据说明】

第1批:第2至4份成绩单,落差值为1,剩余成绩单为76710712;

第2批:第4份成绩单,落差值为0,剩余成绩单为767712;

第3批:第1至4份成绩单,落差值为1,剩余成绩单为12;

第4批:剩余的2份成绩单,落差值为1。

总代价为4×3+(12+02+12+12)×1=15。

HINT

n<=50, a<=100, b<=10, w_i<=1000


思路

首先考虑dp

\(f_{l,r}\)表示把区间\([l,r]\)的所有成绩单删除的代价

然后就不会了,考虑整个区间,要么递归成两个子区间分别处理,或者直接考虑这个区间的最后一次删除

那么最后一次删除的如果是\([p,q]\)这个区间的数,记录\(g_{l,r,p,q}\)表示区间\([l,r]\)最后只剩下\([p,q]\)的最小代价

然后f的转移可以枚举\(p,q\)从g转移也可以划分成两个区间递归成f转移

g可以划分成两个区间,分别从\(g_{l,k,p,q}+g_{k+1,r,p,q},g_{l,k,p,q}+f_{k+1,r},f_{l,k}+g_{k+1,r,p,q}\)转移


#include<bits/stdc++.h>

using namespace std;

const int N = 51;
const int INF_of_int = 1e8; int f[N][N], g[N][N][N][N];
int a, b, n, m, w[N], pre[N]; int getg(int l, int r, int down, int up);
int getf(int l, int r); int getg(int l, int r, int down, int up) {
if (~g[l][r][down][up]) return g[l][r][down][up];
if (l == r) return g[l][r][down][up] = (down <= w[l] && w[l] <= up) ? 0 : INF_of_int;
int &cur = g[l][r][down][up];
cur = INF_of_int;
for (int k = l; k < r; k++) {
cur = min(cur, getg(l, k, down, up) + getg(k + 1, r, down, up));
cur = min(cur, getg(l, k, down, up) + getf(k + 1, r));
cur = min(cur, getf(l, k) + getg(k + 1, r, down, up));
}
return cur;
} int getf(int l, int r) {
if (~f[l][r]) return f[l][r];
if (l == r) return f[l][r] = a;
int &cur = f[l][r];
cur = INF_of_int;
for (int i = 1; i <= m; i++)
for (int j = i; j <= m; j++)
cur = min(cur, getg(l, r, i, j) + a + b * (pre[j] - pre[i]) * (pre[j] - pre[i]));
for (int k = l; k < r; k++)
cur = min(cur, getf(l, k) + getf(k + 1, r));
return cur;
} int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
#endif
memset(f, -1, sizeof(f));
memset(g, -1, sizeof(g));
scanf("%d %d %d", &n, &a, &b);
for (int i = 1; i <= n; i++) {
scanf("%d", &w[i]);
pre[i] = w[i];
}
sort(pre + 1, pre + n + 1);
m = unique(pre + 1, pre + n + 1) - pre - 1;
for (int i = 1; i <= n; i++)
w[i] = lower_bound(pre + 1, pre + m + 1, w[i]) - pre;
printf("%d", getf(1, n));
return 0;
}

BZOJ4897: [Thu Summer Camp2016]成绩单【DP of DP】的更多相关文章

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

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

  2. bzoj4897 [Thu Summer Camp2016]成绩单

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

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

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

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

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

  5. BZOJ 4897: [Thu Summer Camp2016]成绩单 动态规划

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

  6. DP套DP HDOJ 4899 Hero meet devil(国王的子民的DNA)

    题目链接 题意: 给n长度的S串,对于0<=i<=|S|,有多少个长度为m的T串,使得LCS(S,T) = i. 思路: 理解的不是很透彻,先占个坑. #include <bits/ ...

  7. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  8. 377. Combination Sum IV——DP本质:针对结果的迭代,dp[ans] <= dp[ans-i] & dp[i] 找三者关系 思考问题的维度+1,除了数据集迭代还有考虑结果

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  9. [DP]数位DP总结

     数位DP总结 By Wine93 2013.7 1.学习链接 [数位DP] Step by Step   http://blog.csdn.net/dslovemz/article/details/ ...

随机推荐

  1. InChat版,仅仅两个接口实现自己的IM系统(可兼容)

    InChat 一个IM通讯框架 一个轻量级.高效率的支持多端(应用与硬件Iot)的异步网络应用通讯框架.(核心底层Netty) 版本目标:完成基本的消息通讯(仅支持文本消息),离线消息存储,历史消息查 ...

  2. Python处理HTML转义字符

    抓网页数据经常遇到例如>或者 这种HTML转义符,抓到字符串里很是烦人. 比方说一个从网页中抓到的字符串: html = '<abc>' 用Python可以这样处理: import ...

  3. JELLYFISH - Fast, Parallel k-mer Counting for DNA

    kmer分析其实是非常耗费计算资源的,如果我们自己写脚本来分析kmer的话,首先要将所有的序列打断成一定长度的kmer,然后将所有的kmer存储起来,最后统计每个kmer出现的频率,或者统计出现指定次 ...

  4. Confluence 6 使用 LDAP 授权连接一个内部目录 - Schema 设置

    基本 DN(Base DN) 根专有名称(DN),这个名称在你对目录服务器上进行查询的时候使用.例如: o=example,c=com cn=users,dc=ad,dc=example,dc=com ...

  5. Change-free CodeForces - 767E (贪心)

    题目链接 大意:Arseny有m个1元硬币, 无限多100元钞票, 他要按顺序买n个东西, 第i天如果找零x个硬币, 他的不满值会加 w[i]*x, 求最少不满值. 若找零, 则硬币增加 100-ci ...

  6. 自定义DateTimeInput(时间)控件的显示格式

    DateTimeInput控件已有的几种格式可以在Format属性中选择: 但这几种格式仍无法满足我的要求怎么办? 例如想将显示格式定为类似这样的格式:2010-06-11 20:02:52,两步搞定 ...

  7. dp练习(9)——最大乘积

    1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Desc ...

  8. Mac安装fish shell

    1.brew update 2.brew install fish 3.sudo vi /etc/shells 增加内容:/usr/local/bin/fish   ##增加fish到shell环境变 ...

  9. vs2012 怎样解决 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包的问题

    今天用vs2012打开项目总是报这个错误,在网上找到解决方法 1.问题描述: 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPac ...

  10. learning scala read from console

    控制台输入语句: readInt, readDouble, readByte, readShort, readLong, readChar, readBoolean, readLine example ...