题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 999999/400000 K (Java/Others)

Little D is really interested in the theorem of sets recently. There’s a problem that confused him a long time.   
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.

Input

The input contains multiple test cases. 
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.

Output

For each test case, output one line containing exactly one integer, the minimal total cost. Take a look at the sample output for format.

Sample Input

2
3 2
1 2 4
4 2
4 7 10 1

Sample Output

Case 1: 1
Case 2: 18

题意:

给出含有N元素的集合S,选取M个S的子集,要求满足SU S2 U … U SM = S;

定义一个集合的最大元素为MAX,最小元素为MIN,它的花费为(MAX - MIN)2,现要求所有子集的总花费最少为多少。

题解:

先将S内元素从小到大排列,然后将这N个元素的序列分成M组(因为若有重叠元素,必然会使得花费增加);

那么假设dp[i][j]为前i个数分成j组的最小花费,那么求出dp[N][M]即可回答问题;

状态转移方程为dp[i][j] = min{ dp[k][j-1] + (S[i] - S[k+1])2 },j-1≤k<i;

那么当j固定时,计算dp[i][j]时需要枚举k,若k可能取值到a,b两点,且j-1≤a<b<i,

若有 dp[b][j-1] + (S[i] - S[b+1])2 ≤ dp[a][j-1] + (S[i] - S[a+1])2,则b点优于a点;

将上式变形,得到:

b点优于a点 <=> 

再然后就是斜率优化的老套路了(斜率优化的详情查看斜率DP分类里之前的文章),就不再赘述。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=+; int n,m,S[maxn];
int dp[maxn][maxn];
int q[maxn],head,tail; int up(int a,int b,int j) //g(a,b)的分子部分
{
return (dp[b][j-]+S[b+]*S[b+])-(dp[a][j-]+S[a+]*S[a+]);
}
int down(int a,int b) //g(a,b)的分母部分
{
return *S[b+]-*S[a+];
} int main()
{
int t;
scanf("%d",&t);
for(int kase=;kase<=t;kase++)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&S[i]);
sort(S+,S+n+); for(int i=;i<=n;i++) dp[i][]=(S[i]-S[])*(S[i]-S[]);
for(int j=;j<=m;j++)
{
head=tail=;
q[tail++]=j-;
for(int i=j;i<=n;i++)
{
while(head+<tail)
{
int a=q[head], b=q[head+];
if(up(a,b,j)<=S[i]*down(a,b)) head++; //g(a,b)<=S[i]
else break;
}
int k=q[head];
dp[i][j]=dp[k][j-]+(S[i]-S[k+])*(S[i]-S[k+]); while(head+<tail)
{
int a=q[tail-], b=q[tail-];
if(up(a,b,j)*down(b,i)>=up(b,i,j)*down(a,b)) tail--; //g(a,b)>=g(b,i)
else break;
}
q[tail++]=i;
}
} printf("Case %d: %d\n",kase,dp[n][m]);
}
}

注意DP边界的初始化。

HDU 3480 - Division - [斜率DP]的更多相关文章

  1. hdu 3480 Division(斜率优化DP)

    题目链接:hdu 3480 Division 题意: 给你一个有n个数的集合S,现在让你选出m个子集合,使这m个子集合并起来为S,并且每个集合的(max-min)2 之和要最小. 题解: 运用贪心的思 ...

  2. HDU 2829 - Lawrence - [斜率DP]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2829 T. E. Lawrence was a controversial figure during ...

  3. ACM-ICPC 2016 沈阳赛区现场赛 I. The Elder && HDU 5956(斜率DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5956 题意:一颗树上每条边有个权值,每个节点都有新闻要送到根节点就是1节点,运送过程中如果不换青蛙就是 ...

  4. HDU 3480 Division(斜率DP裸题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480 题目大意:将n个数字分成m段,每段价值为(该段最大值-该段最小值)^2,求最小的总价值. 解题思 ...

  5. HDU 3480 Division(斜率优化+二维DP)

    Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others) Tota ...

  6. HDU 3480 Division DP斜率优化

    解题思路 第一步显然是将原数组排序嘛--然后分成一些不相交的子集,这样显然最小.重点是怎么分. 首先,我们写出一个最暴力的\(DP\): 我们令$F[ i ][ j ] $ 为到第\(i\)位,分成\ ...

  7. HDU 3480 division

    题目大意:一个有n个数的集合,现在要求将他分成m+1个子集,对子集i设si表示该集合中最大数与最小数的差的平方.求所有si的和的最小值.n<=10000,m<=5000. 分析:最优解的m ...

  8. hdu 3480 Division(四边形不等式优化)

    Problem Description Little D is really interested in the theorem of sets recently. There’s a problem ...

  9. hdu 2829 Lawrence(斜率优化DP)

    题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...

随机推荐

  1. 关于Android中Animation的停止【转载】

    转载自:http://blog.csdn.net/easonx1990/article/details/8231520 最近遇到一个需求,通过在GridView上改变焦点,并且GridView上每个i ...

  2. Mac OS 电信3G上网设置

    打开客户端后(安装客户端mobile partner需要先安装jdk),在“系统偏好设置”里选择“网络”,网络左侧添加“huaweimobile-modem”,“电话号码”填写电信卡号,“账户名称”和 ...

  3. Linux常用命令总结--基础命令

    系统信息 1.arch 显示机器的处理器架构(1) 2.uname -m 显示机器的处理器架构(2) 3.lsb_release -a 查看操作系统版本 4.top 查看进程 5.free -m 查看 ...

  4. Yii 汉化翻译

    一).首先创建一个zh_cn语言包.(参考网址:制作语言包) 1.复制framework\messages\config.php 文件到 protected\messages\下 2.更改config ...

  5. MySQL用户认证及权限控制

    一.MySQL用户认证: 登录并不属于访问控制机制,而属于用户身份识别和认证: 1.用户名—user 2.密码—password 3.登录mysqld主机—host 实现用户登录MySQL,建立连接. ...

  6. systemctl命令完全指南

    Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器. Systemd是一个系统管理守护进程.工具和库的集合,用于取代System V初始进程.Systemd的功能是 ...

  7. PowerShell的初步学习

    今天要重新学习一钟语法,由于工作中项目的需要,不得不说学习新的语言是必不可少的.          Windows PowerShell 是一种命令行外科程序和脚本环境,使命令行用户和脚本编写者可以利 ...

  8. 在mac终端先打开mysql

    以打开xampp下的mysql为例: mysql执行文件是放在bin目录下的,不要cd bin后键入mysql,而应该直接在bin的上级目录时键入bin/mysql,这样才能进入到mysql命令行模式 ...

  9. Contain的使用

  10. Qt5 教程

    序 Qt 前言 Hello, world! 信号槽 自定义信号槽 Qt 模块简介 MainWindow 简介 添加动作 资源文件 对象模型 布局管理器 菜单栏.工具栏和状态栏 对话框简介 对话框数据传 ...