题目链接

BZOJ4897

题解

发现我们付出的代价与区间长度无关,而与区间权值范围有关

离散化一下权值

我们设\(f[l][r][x][y]\)表示区间\([l,r]\)消到只剩权值在\([x,y]\)所需最小代价

\(f[l][r][0][0]\)即为消完的最小代价

那么

\[f[l][r][0][0] = min\{f[l][r][x][y] + a + b(w[y] - w[x])^2\}
\]

转移的话,贪心地取出区间两边在权值区间\([x,y]\)以内的数,剩下区间\([l',r']\)

如果剩余区间直接消去,可以直接计算

如果不一次消去,那么枚举断点转移即可

复杂度小常数\(O(n^5)\)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 55,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int f[maxn][maxn][maxn][maxn],n,a,b,w[maxn],c[maxn],tot;
void cmin(int& x,int y){x = min(x,y);}
int main(){
n = read(); a = read(); b = read();
REP(i,n) c[i] = w[i] = read();
sort(c + 1,c + 1 + n); tot = 1;
for (int i = 2; i <= n; i++) if (c[i] != c[tot]) c[++tot] = c[i];
for (int i = 1; i <= n; i++) w[i] = lower_bound(c + 1,c + 1 + tot,w[i]) - c;
for (int l = 1; l <= n; l++)
for (int r = l; r <= n; r++){
int mx = -INF,mn = INF;
for (int k = l; k <= r; k++)
mx = max(mx,w[k]),mn = min(mn,w[k]);
f[l][r][0][0] = a + b * (c[mx] - c[mn]) * (c[mx] - c[mn]);
for (int x = 1; x <= tot; x++)
for (int y = x; y <= tot; y++)
f[l][r][x][y] = INF;
}
for (int len = 1; len <= n; len++){
for (int l = 1; l + len - 1 <= n; l++){
int r = l + len - 1;
for (int x = 1; x <= tot; x++)
for (int y = x; y <= tot; y++){
int ll = l,rr = r;
while (ll <= r && w[ll] >= x && w[ll] <= y) ll++;
while (rr >= ll && w[rr] >= x && w[rr] <= y) rr--; if (ll > rr) f[l][r][x][y] = 0;
else if (ll == rr) f[l][r][x][y] = a;
else {
for (int k = ll; k < rr; k++){
cmin(f[l][r][x][y],f[ll][k][x][y] + f[k + 1][rr][x][y]);
cmin(f[l][r][x][y],f[ll][k][0][0] + f[k + 1][rr][x][y]);
cmin(f[l][r][x][y],f[ll][k][x][y] + f[k + 1][rr][0][0]);
cmin(f[l][r][x][y],f[ll][rr][0][0]);
}
}
}
for (int x = 1; x <= tot; x++)
for (int y = x; y <= tot; y++)
cmin(f[l][r][0][0],a + b * (c[y] - c[x]) * (c[y] - c[x]) + f[l][r][x][y]);
}
}
printf("%d\n",f[1][n][0][0]);
return 0;
}

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

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

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

  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. [BZOJ4897][THUSC2016]成绩单(DP)

    4897: [Thu Summer Camp2016]成绩单 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 220  Solved: 132[Subm ...

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

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

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

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

  9. BZOJ4896 [Thu Summer Camp2016]补退选 【trie树】

    题目链接 BZOJ4896 题解 \(thu\)怎么那么喜欢出\(trie\)树的题... 我们当然可以按题意模拟建\(trie\) 询问的时候,由于存在删除操作,不满足单调性,不能直接二分答案 我们 ...

随机推荐

  1. 92套AE抖音快闪模板(精品)

    包含很多场景和类型,直接用即可,下载地址:百度网盘,https://pan.baidu.com/s/1bRFql1zFWyfpTAwa6MhuPA 内容截图:    

  2. 了解Python控制流语句——continue 语句

    continue 语句用以告诉 Python 跳过当前循环块中的剩余语句,并继续该循环的下一次迭代. 案例(保存为 continue.py): while True: s = input('Enter ...

  3. es6笔记4^_^function

    一.function默认参数 现在可以在定义函数的时候指定参数的默认值了,而不用像以前那样通过逻辑或操作符来达到目的了. es5 function sayHello(name){ //传统的指定默认参 ...

  4. 《Effective C++》读书笔记 资源管理

    C++程序中最常用的资源包括动态分配的内存,文件描述器,互斥锁,数据库连接,网络socket等等.不论哪种资源,重要的是,当你不再使用他时,必须将他归还给系统. 一个很好的做法是以对象管理资源.把资源 ...

  5. sparksql读写hbase

    //写入hbase(hfile方式) org.apache.hadoop.hbase.client.Connection conn = null; try { SparkLog.debug(" ...

  6. POJ 3845 Fractal(计算几何の旋转缩放)

    Description Fractals are really cool mathematical objects. They have a lot of interesting properties ...

  7. 一次大量TIME_WAIT和Recv-Q 堵塞问题排查思路

    记录一下周末出现问题~     仅自己摘记不做任何参考. 第一天故障: 现象: 公司销售群和售后群炸了,说老后台(1.0版本)崩溃了,因为还有部门的业务没来得及迁移到新后台,我当时正在打农药哈哈~ 后 ...

  8. Java Class Object

    Object类 它是所有类的基类. public class Person { } //实际上是 public class Person extends Object { } Object类的方法 t ...

  9. Java中I/O流之数据流

    Java 中的数据流: 对于某问题:将一个 long 类型的数据写到文件中,有办法吗?    转字符串 → 通过 getbytes() 写进去,费劲,而且在此过程中 long 类型的数需要不断地转换. ...

  10. <Effective C++>读书摘要--Implementations<一>

    1.For the most part, coming up with appropriate definitions for your classes (and class templates) a ...