题意:给你n个数,然后让你分成m个集合,每个集合有一个值(最大值减最小值,然后平方),求整个集合的可能最小值。

思路:因为每个集合里的值只和最大和最小值有关,所以很容易想到先排序,然后用DP可求得解,状态转移方程dp[i][j] = min(dp[i][j] , dp[k][j - 1] + (a[i] - a[k + 1]) ^ 2),j表示数组的下标,i表示集合数,dp为最小值,但是因为n为10000,m为5000,这个复杂度肯定会超时,所以可以用斜率或四边形优化来减小复杂度,式子就不证明了,这里直接引用,另外贴上四边形优化的一个链接,讲的挺详细的点击打开链接

#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 10010
#define ll long long
using namespace std; ll a[MAXN];
ll dp[MAXN][MAXN];
int N, M;
ll q[MAXN];
ll head, tail; void init()
{
for (int i = 1; i <= N; i++)
dp[1][i] = (a[i] - a[1])*(a[i] - a[1]);
} void solve()
{
for(int i=2;i<= M;i++)
{
head=tail=0;
q[tail++]=i-1;
for(int j = i;j <= N;j++)
{
while(head+1<tail)
{
int p1=q[head];
int p2=q[head + 1];
int x1=a[p1 + 1];
int x2=a[p2 + 1];
int y1=dp[i - 1][p1] + x1*x1;
int y2=dp[i - 1][p2] + x2*x2;
if((y2-y1)<= 2*a[j]*(x2-x1))head++;
else break;
}
int k=q[head];
dp[i][j]=dp[i-1][k]+(a[j]-a[k+1])*(a[j]-a[k+1]);
while(head+1<tail)
{
int p1=q[tail-2];
int p2=q[tail-1];
int p3=j;
int x1=a[p1+1];
int x2=a[p2+1];
int x3=a[p3+1];
int y1=dp[i-1][p1]+x1*x1;
int y2=dp[i-1][p2]+x2*x2;
int y3=dp[i-1][j]+x3*x3;
if ((y3-y2)*(x2-x1)<=(y2-y1)*(x3-x2))tail--;
else break;
}
q[tail++]=j;
}
}
}
int main()
{
int T;
scanf("%d",&T);
int k=0;
while(T--)
{
k++;
scanf("%d%d",&N,&M);
for (int i = 1; i <= N; i++)
scanf("%d", &a[i]);
sort(a+1,a+N+1);
init();
solve();
printf("Case %d: %d\n",k,dp[M][N]);
}
return 0;
}

HDU3480的更多相关文章

  1. HDU3480 Division —— 斜率优化DP

    题目链接:https://vjudge.net/problem/HDU-3480 Division Time Limit: 10000/5000 MS (Java/Others)    Memory ...

  2. hdu3480二维斜率优化DP

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

  3. hdu3480 Division(dp平行四边形优化)

    题意:将n个数分成m段,每段的代价为最大值减最小值的平方,为代价最小是多少n<=10000 ,m<=5000 题解:先拍好序,从小到大,这样绝对是花费最小的,不过怎么样来做呢?一定很容易想 ...

  4. HDU-3480 Division (四边形不等式优化DP)

    题目大意:将n个数分成m组,将每组的最大值与最小值的平方差加起来,求最小和. 题目分析:先对数排序.定义状态dp(i,j)表示前 j 个数分成 i 组得到的最小和,则状态转移方程为dp(i,j)=mi ...

  5. HDU3480:Division——题解

    http://acm.hdu.edu.cn/showproblem.php?pid=3480 将一列数划分成几个集合,这些集合的并集为该数列,求每个数列的(最大值-最小值)^2的和的最小值. 简单的d ...

  6. [HDU3480] Division [四边形不等式dp]

    题面: 传送门 思路: 因为集合可以无序选择,所以我们先把输入数据排个序 然后发先可以动归一波 设$dp\left[i\right]\left[j\right]$表示前j个数中分了i个集合,$w\le ...

  7. HDU3480 Division——四边形不等式或斜率优化

    题目大意 将N个数分成M部分,使每部分的最大值与最小值平方差的和最小. 思路 首先肯定要将数列排序,每部分一定是取连续的一段,于是就有了方程 $\Large f(i,j)=min(f(i-1,k-1) ...

  8. hdu3480 Division

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

  9. 单调队列 && 斜率优化dp 专题

    首先得讲一下单调队列,顾名思义,单调队列就是队列中的每个元素具有单调性,如果是单调递增队列,那么每个元素都是单调递增的,反正,亦然. 那么如何对单调队列进行操作呢? 是这样的:对于单调队列而言,队首和 ...

随机推荐

  1. smali文件语法参考

    Dalvik opcodes Author: Gabor Paller Vx values in the table denote a Dalvik register. Depending on th ...

  2. 抽象数据类型Triplet的C语言实现

    #include <stdio.h> #include <stdlib.h> #define ERROR 0 #define OK 1 typedef int Status; ...

  3. Unity问答——请问一下动画状态机怎么判断动画是否播完了?

    这篇博客源自我在泰课在线的回答.链接:http://www.taikr.com/group/1/thread/233 问:请问一下动画状态机怎么判断动画是否播完了? 答: 1. 脚本参考 Animat ...

  4. Google为何这么屌

    概述: 在移动市场上,从来没有一个公司像Google一样的玩法,以后可能也不会有.因为这根本就不是一个商业模式.它可以调动极大的资源而几乎没有盈利压力,它力逾千钧又身段灵活.它从来不尊重这个市场原有的 ...

  5. JSP - request - 1

    <%@ page language="java" contentType="text/html;charset=utf8" %> <%@ pa ...

  6. BZOJ 3884 上帝与集合的正确用法

    Description 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做"元". 第二天, 上帝创造了一个新的元素,称作&quo ...

  7. Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条

    Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条 异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Ap ...

  8. hdu 5150 Sit sit sit

    http://acm.hdu.edu.cn/showproblem.php?pid=5151 直接判断是不是素数,然后再注意1就行. #include <cstdio> #include ...

  9. Delphi文件映射

    http://www.cnblogs.com/key-ok/p/3429860.htmlhttp://www.cnblogs.com/key-ok/p/3380793.htmlhttp://www.c ...

  10. UVA 10706 Number Sequence (找规律 + 打表 + 查找)

    Problem B Number Sequence Input: standard input Output: standard output Time Limit: 1 second A singl ...