HDU3480 Division —— 斜率优化DP
题目链接:https://vjudge.net/problem/HDU-3480
Division
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 999999/400000 K (Java/Others)
Total Submission(s): 5304 Accepted Submission(s): 2093
Let T be a set of integers. Let the MIN be the minimum integer in T and MAX be the maximum, then the cost of set T if defined as (MAX – MIN)^2. Now given an integer set S, we want to find out M subsets S1, S2, …, SM of S, such that

and the total cost of each subset is minimal.
In the first line of the input there’s an integer T which is the number of test cases. Then the description of T test cases will be given.
For any test case, the first line contains two integers N (≤ 10,000) and M (≤ 5,000). N is the number of elements in S (may be duplicated). M is the number of subsets that we want to get. In the next line, there will be N integers giving set S.
3 2
1 2 4
4 2
4 7 10 1
Case 2: 18
The answer will fit into a 32-bit signed integer.
题意:
给出一组数,把这组数分成m个集合,使得每个集合的(MAX-MIN)^2的和最小。
题解:
1.首先可以确定:每个集合的数值跨度应该尽量小,所以可以先对这些数进行排序,被分成一组的数必定是相连的。
2.设dp[i][j]为:第j个数属于第i个集合时的最小值,那么:dp[i][j] = min(dp[i-1][k] + (val[i] - val[k+1)^2),其中 i-1<=k<=j-1。
3.根据上述的状态转移方程,可算得时间复杂度为O(n^3),无法接受。因此可以用斜率优化。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int MAXM = 1e5+;
const int MAXN = 1e4+; int val[MAXN], dp[MAXN][MAXN];
int q[MAXN], head, tail; int getUP(int i, int k1, int k2)
{
return (dp[i-][k1] + val[k1+]*val[k1+])-
(dp[i-][k2] + val[k2+]*val[k2+]);
} int getDOWN(int k1, int k2)
{
return *(val[k1+]-val[k2+]);
} int getDP(int i, int j, int k)
{
return dp[i-][k] + (val[j]-val[k+])*(val[j]-val[k+]);
} int main()
{
int n, m, T;
scanf("%d", &T);
for(int kase = ; kase<=T; kase++)
{
scanf("%d%d", &n,&m);
for(int i = ; i<=n; i++)
scanf("%d", &val[i]); sort(val+, val++n);
for(int i = ; i<=n; i++) //初始化第一段
dp[][i] = (val[i]-val[])*(val[i]-val[]);
for(int i = ; i<=m; i++) //从i-1段转移到i段
{
head = tail = ;
q[tail++] = i-; //i-1段最少要有i-1个数,故从i-1开始
for(int j = i; j<=n; j++) //i段最少要有i个数,故从i开始
{
while(head+<tail && getUP(i,q[head+],q[head])<getDOWN(q[head+], q[head])*val[j]) head++;
dp[i][j] = getDP(i,j,q[head]); while(head+<tail && getUP(i,j,q[tail-])*getDOWN(q[tail-],q[tail-])<=
getUP(i,q[tail-],q[tail-])*getDOWN(j,q[tail-])) tail--;
q[tail++] = j;
}
}
printf("Case %d: %d\n", kase, dp[m][n]);
}
}
HDU3480 Division —— 斜率优化DP的更多相关文章
- hdu 3480 Division(斜率优化DP)
题目链接:hdu 3480 Division 题意: 给你一个有n个数的集合S,现在让你选出m个子集合,使这m个子集合并起来为S,并且每个集合的(max-min)2 之和要最小. 题解: 运用贪心的思 ...
- hdu 2829 Lawrence(斜率优化DP)
题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...
- HDU2829 Lawrence —— 斜率优化DP
题目链接:https://vjudge.net/problem/HDU-2829 Lawrence Time Limit: 2000/1000 MS (Java/Others) Memory L ...
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- BZOJ 3156: 防御准备 斜率优化DP
3156: 防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...
随机推荐
- 查找系列合集-二叉查找树BST
一. 二叉树 1. 什么是二叉树? 在计算机科学中,二叉树是每个结点最多有两个子树的树结构. 通常子树被称作“左子树”(left subtree)和“右子树”(right subtree). 二叉树常 ...
- Noip2016题解&总结
原文放在我的uoj博客上,既然新开了blog,那就移过来了 玩具谜题(toy) 送分题.没有什么好说的. 直接按照题目的要求模拟即可. 标准的noip式day1T1. #include<cstd ...
- 第4章 CentOS软件安装
一.安装JDK 1.1 卸载旧版JDK 首先,在你的服务器上运行一下更新. yum update 然后,在您的系统上搜索,任何版本的已安装的JDK组件. rpm -qa | grep -E '^ope ...
- 深入理解Atomic原子类
Atomic是基于unsafe类和自旋操作实现的,下面以AtomicInteger类为例进行讲解. 要理解Atomic得先了解CAS CAS CAS全程Compare And Swap ,是条并发原语 ...
- RabbitMQ 最常用的三大模式
目录 Direct 模式 Topic 模式 Fanout 模式 Direct 模式 所有发送到 Direct Exchange 的消息被转发到 RouteKey 中指定的 Queue. Direct ...
- Java文件夹操作,判断多级路径是否存在,不存在就创建(包括windows和linux下的路径字符分析),兼容Windows和Linux
兼容windows和linux. 分析: 在windows下路径有以下表示方式: (标准)D:\test\1.txt (不标准,参考linux)D:/test/1.txt 然后在java中,尤其使用F ...
- [转] 常用SQL查询语句
sunada 的原文地址 常用SQL查询语句 一.简单查询语句 1. 查看表结构 SQL>DESC emp; 2. 查询所有列 SQL>SELECT * FROM emp; 3. 查询指 ...
- fastscript增加公共函数
fastscript增加公共函数 unit fs_BsCommFuncs; interface{$i fs.inc}uses SysUtils, Classes, fs_iclassesrtti, f ...
- Git安装及SSH Key管理之Mac篇
1.下载git客户端,下载地址为:https://git-scm.com/download/mac 2.打开安装包,可以看到此时的界面为: 我们需要把.pkg的安装包安装到系统当中.我双击了安装包 ...
- 基于ACCESS和ASP的SQL多个表查询与计算统计代码(一)
近期在写几个关于"Project - Subitem - Task"的管理系统,说是系统还是有点夸大了,基本就是一个多表查询调用和insert.update的数据库操作.仅仅是出现 ...