Division

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

Total Submission(s): 2664    Accepted Submission(s): 1050

Problem Description
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

/*分析:
首先对于斜率dp我有个总结:
斜率dp一般应用于连续的一段或几段求最值
既1~k,k+1~j,j+1~...这样分段而不能跳开来求
仅仅有连续段才干用单调队列维护最值然后
dp[i]=dp[j]+(j+1~i)的值。 对于本题:
题目要求m个子数组的最值。而子数组中的元素不一定是原数组连续的
所以肯定不能直接用斜率优化,经过分析能够发现先进行从小到大排序
然后连续的m段最值就是能够求最值了。 所以:先对原数组进行从小到大排序
dp[i][j]表示以i结尾的j段的最值
从k+1~i作为一段
则:dp[i][j]=dp[k][j-1]+(s[i]-s[k+1])^2
如今就是怎样求到这个k使得dp[i][j]最小
如果k2<=k1<i
若:dp[k1][j-1]+(s[i]-s[k1+1])^2 <= dp[k2][j-1]+(s[i]-s[k2+1])^2
=>dp[k1][j-1]+s[k1+1]^2 - (dp[k2][j-1]+s[k2+1]^2) / (2s[k1+1]-2s[k2+1]) <= s[i]
所以:
y1 = dp[k1][j-1]+s[k1+1]^2
x1 = 2s[k1+1]
y2 = dp[k2][j-1]+s[k2+1]^2
x2 = 2s[k2+1] =>(y1 - y2)/(x1 - x2) <= i
单调队列维护下凸折线
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <iomanip>
#include <limits.h>
#define INF 99999999
typedef long long LL;
using namespace std; const int MAX = 10000+10;
int n,m,index;
int q[MAX];
int s[MAX],dp[2][MAX];//採用滚动数组 int GetY(int k1,int k2){
return dp[index^1][k1]+s[k1+1]*s[k1+1] - (dp[index^1][k2]+s[k2+1]*s[k2+1]);
} int GetX(int k1,int k2){
return 2*(s[k1+1]-s[k2+1]);
} int DP(){
int head=0,tail=1;
index=0;
for(int i=1;i<=n;++i)dp[index][i]=INF;//初始化
//dp[index][0]=0;
for(int i=1;i<=m;++i){
index=index^1;
head=tail=0;
q[tail++]=0;
for(int j=1;j<=n;++j){
//dp[index^1][0]=(i-1)*(s[j]-s[1])*(s[j]-s[1]);
while(head+1<tail && GetY(q[head+1],q[head]) <= GetX(q[head+1],q[head])*s[j])++head;
while(head+1<tail && GetY(j,q[tail-1])*GetX(q[tail-1],q[tail-2]) <= GetY(q[tail-1],q[tail-2])*GetX(j,q[tail-1]))--tail;
q[tail++]=j;
int k=q[head];
dp[index][j]=dp[index^1][k]+(s[j]-s[k+1])*(s[j]-s[k+1]);
}
}
return dp[index][n];
} int main(){
int t,num=0;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%d",s+i);
sort(s+1,s+1+n);
printf("Case %d: %d\n",++num,DP());
}
return 0;
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

hdu3480二维斜率优化DP的更多相关文章

  1. 2019.03.28 bzoj3594: [Scoi2014]方伯伯的玉米田(二维bit优化dp)

    传送门 题意咕咕咕 思路:直接上二维bitbitbit优化dpdpdp即可. 代码: #include<bits/stdc++.h> #define N 10005 #define K 5 ...

  2. 斜率优化DP学习笔记

    先摆上学习的文章: orzzz:斜率优化dp学习 Accept:斜率优化DP 感谢dalao们的讲解,还是十分清晰的 斜率优化$DP$的本质是,通过转移的一些性质,避免枚举地得到最优转移 经典题:HD ...

  3. BZOJ 1010 [HNOI2008]玩具装箱 (斜率优化DP)

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 思路 [斜率优化DP] 我们知道,有些DP方程可以转化成DP[i]=f[j]+x[i ...

  4. [CEOI2004]锯木厂选址 斜率优化DP

    斜率优化DP 先考虑朴素DP方程, f[i][k]代表第k个厂建在i棵树那里的最小代价,最后答案为f[n+1][3]; f[i][k]=min(f[j][k-1] + 把j+1~i的树都运到i的代价) ...

  5. bzoj1010: [HNOI2008]玩具装箱toy(斜率优化DP)

    Orz CYC帮我纠正了个错误.斜率优化并不需要决策单调性,只需要斜率式右边的式子单调就可以了 codevs也有这题,伪·双倍经验233 首先朴素DP方程很容易看出:f[i]=min(f[j]+(i- ...

  6. 【转】斜率优化DP和四边形不等式优化DP整理

    (自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...

  7. HDU2829 Lawrence —— 斜率优化DP

    题目链接:https://vjudge.net/problem/HDU-2829 Lawrence Time Limit: 2000/1000 MS (Java/Others)    Memory L ...

  8. BZOJ 3675 APIO2014 序列切割 斜率优化DP

    题意:链接 方法:斜率优化DP 解析:这题BZ的数据我也是跪了,特意去网上找到当年的数据后面二十个最大的点都过了.就是过不了BZ. 看到这道题自己第一发DP是这么推得: 设f[i][j]是第j次分第i ...

  9. 【学习笔记】动态规划—斜率优化DP(超详细)

    [学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...

随机推荐

  1. uvalive 2911 Maximum(贪心)

    题目连接:2911 - Maximum 题目大意:给出m, p, a, b,然后xi满足题目中的两个公式, 要求求的 xp1 + xp2 +...+ xpm 的最大值. 解题思路:可以将x1 + x2 ...

  2. 使用C++名单在文档处理和学生成绩管理系统相结合

    对于学生成绩管理系统,我并不陌生,几乎学习C人的语言.做项目会想到学生成绩管理系统,我也不例外.在研究中的一段时间C语言之后,还用C语言到学生管理系统,然后做几个链接.计数,这个系统是以前的系统上的改 ...

  3. hdu 4882 ZCC Loves Codefires(数学题+贪心)

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

  4. NET 分布式架构开发项目实战

    .NET 分布式架构开发项目实战 从头到尾,一步一步讲述一个真实的项目实战,关注点主要是架构的思考和实现,以及如何解决平时项目遇到的一些问题. 同时也司公布源代码. 如何构建高性能,稳定SOA应用之- ...

  5. Cluster Table

    对簇表来说,总是要先创建簇段(cluster segment).然后将表关联到cluster segment里.由此可知,簇表也是虚拟表,没有对应的segment,簇表对应的是cluster segm ...

  6. SQL Server提高并发查询效率

    同事写了个程序用创建多个线程使用ado同时对同个数据库进行相同的查询,涉及2张数据表的联查.当线程数非常多的情况下,读取数据的效率就会变得很慢,例如50个线程同时查询大概3000条数据,查询完成后通过 ...

  7. 【Swift】学习笔记(一)——熟知 基础数据类型,编码风格,元组,主张

    自从苹果宣布swift之后,我一直想了解,他一直没有能够把它的正式学习,从今天开始,我会用我的博客来驱动swift得知,据我们了解还快. 1.定义变量和常量 var  定义变量,let定义常量. 比如 ...

  8. SharePoint 2010 BCS - 概要

    博客地址 http://blog.csdn.net/foxdave SharePoint 2010首次引入了BCS的概念 - Business Connectivity Service.即业务连接服务 ...

  9. .net 一些常用的工具来破解

    在.net  我们经常提到破 Reflector\SimpleAssemblyExplorer和CFF Explore几个工具. 我们有一个非常简单的Windows Form方案,例如,说他们如何使用 ...

  10. 玩转html5(一)-----盘点html5新增的那些酷酷的input类型和属性

    今天正式开始学习html5了,相比html以前的版本,html5新增了好多功能,属性,使我们做出来的界面更加的绚丽,而且使用起来超级简单,这篇文章先来说说html增加的那些input类型和属性. 这些 ...