首先想到的就是sort一下,然后每个集合都在排过序的数组里面取,不重复。

这样就推出公式dp[i][j] = min(dp[k][j-1] + (s[i]-s[k+1])^2)

其中dp[i][j]为在第i位完成j个分组的。

不考虑分组的情况下跟打印文章那题一样。考虑上需要有M个分组,就是两层for循环的dp。

这里往维护的凸包里添加点的时候,要等这一层全部解决之后再一起添进去。保证处理dp第j层时考虑的都是j-1层的情况。

还有就是初始化了。

O(N*M)大概5e7 有点卡,第一次写了个set就TLE了

 #include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std; const int maxn = 1e4+;
const int maxm = 5e3+; struct Point{
LL x,y;
Point(LL _x=,LL _y=) :x(_x),y(_y){}
bool operator < (const Point &rhs) const
{
if(x == rhs.x) return y < rhs.y;
else return x <rhs.x;
}
LL operator ^(const Point &rhs) const
{
return x*rhs.y - y*rhs.x;
}
Point operator - (const Point &rhs) const
{
return Point(x-rhs.x,y-rhs.y);
}
};
LL func(Point p,LL k)
{
return p.y - k*p.x;
} struct SlopeDP
{
Point ch[maxn];
int head,tail;
void init()
{
tail = ;head = ;
}
void push(Point u)
{
while(head >= && ((ch[head]-ch[head-])^(u-ch[head]) )<=) head--;
ch[++head] = u;
}
Point pop(int k)
{
while(tail < head && func(ch[tail],k) >= func(ch[tail+],k) ) tail++;
return ch[tail];
}
};
int T,N,M;
LL s[maxn],dp[maxn][maxm];
//set <Point> st;
Point save[maxn]; int main()
{
scanf("%d",&T);
int cas = ;
while(T--)
{
memset(dp,,sizeof dp);
scanf("%d%d",&N,&M);
for(int i=;i<=N;i++)
{
scanf("%d",&s[i]);
}
sort(s+,s++N);
SlopeDP H;
H.init();
//st.clear();
int cnt = ;
for(int i=;i<=N;i++)
{
dp[i][] = (s[i] - s[])*(s[i] - s[]);
//st.insert(Point(s[i],s[i]*s[i]+dp[i-1][1]));
save[cnt++] = Point(s[i],s[i]*s[i]+dp[i-][]);
} for(int j=;j<=M;j++)
{
H.init();
for(int i=;i<cnt;i++) H.push(save[i]);
cnt = ;
for(int i=j;i<=N;i++)
{
Point u = H.pop(*s[i]);
dp[i][j] = -*s[i]*u.x + u.y + s[i]*s[i];
//printf("i:%d %d x:%d y:%d k:%d\n",i,dp[i][j],u.x,u.y,-2*s[i]);
//H.push(Point(s[i+1],s[i+1]*s[i+1]+dp[i][j]));
save[cnt++] = Point(s[i+],s[i+]*s[i+]+dp[i][j]);
}
}
printf("Case %d: %lld\n",++cas,dp[N][M]);
}
}

HDU3480-Division-斜率dp的更多相关文章

  1. HDU3480 Division —— 斜率优化DP

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

  2. HDU 3480 - Division - [斜率DP]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

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

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

  4. [kuangbin带你飞]专题二十 斜率DP

            ID Origin Title   20 / 60 Problem A HDU 3507 Print Article   13 / 19 Problem B HDU 2829 Lawr ...

  5. bzoj4518: [Sdoi2016]征途--斜率DP

    题目大意:把一个数列分成m段,计算每段的和sum,求所有的sum的方差,使其最小. 由方差*m可以化简得ans=m*sigma(ki^2)-sum[n]^2 很容易得出f[i][j]=min{f[i- ...

  6. hdu 3507 斜率dp

    不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个 ...

  7. 斜率dp cdq 分治

    f[i] = min { f[j] + sqr(a[i] - a[j]) } f[i]= min { -2 * a[i] * a[j] + a[j] * a[j] + f[j] } + a[i] * ...

  8. HDU 2829 Lawrence (斜率DP)

    斜率DP 设dp[i][j]表示前i点,炸掉j条边的最小值.j<i dp[i][j]=min{dp[k][j-1]+cost[k+1][i]} 又由得出cost[1][i]=cost[1][k] ...

  9. 斜率DP题目

    uva 12524 题意:沿河有n个点,每个点有w的东西,有一艘船从起点出发,沿途可以装运东西和卸载东西,船的容量无限,每次把wi的东西从x运到y的花费为(y-x)*wi; 问把n个点的东西合并成k个 ...

  10. bzoj 3156 防御准备(斜率DP)

    3156: 防御准备 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 837  Solved: 395[Submit][Status][Discuss] ...

随机推荐

  1. configure: error: cannot guess build type; you must specify one解决方法

    原文地址:https://blog.csdn.net/hebbely/article/details/53993141 1.configure: error: cannot guess build t ...

  2. Python-sys模块-61

    sys 模块:和Python解释器打交道的模块 sys模块是与python解释器交互的一个接口 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退 ...

  3. H5 32-百度首页

    32-百度首页 新 闻 网 页 贴 吧 知 道 音 乐 图 片 视 频 地 图 百科 文库 hao123 | 更多>> 百度地图带你吃喝玩乐,全心全意为人民服务 把百度设为主页 安装百度卫 ...

  4. H5 16-并集选择器

    16-并集选择器 我是标题 我是段落 我是段落 我是段落 <!DOCTYPE html> <html lang="en"> <head> < ...

  5. C. Ayoub and Lost Array

    链接 [https://codeforces.com/contest/1105/problem/C] 题意 给你n,表示数组长度,元素的值是l到r,问有多少种方案使得所有元素和整除3 分析 思维dp, ...

  6. UnderWater+SDN论文之三

    Software-Defined Underwater Acoustic Modems: Historical Review and the NILUS Approach Source: IEEE J ...

  7. Redis客户端断开重连功能要点

    Redis客户端: Java基于Jedis开发 C#基于StackExchange开发 C++基于acl开发 首先确保在主从模式下,客户端能分辨主从节点,自动连接正确的客户端,这样只要有一个节点可用, ...

  8. 线程中的current thread not owner异常错误

    多线程常用的一些方法: wait(),wait(long),notify(),notifyAll()等 这些方法是当前类的实例方法, wait()      是使持有对象锁的线程释放锁;wait(lo ...

  9. python_线程的开启、守护线程、锁、死锁、事件、定时器、条件、队列、池

    0.承上 什么是线程? CPU调度的最小单位. 线程是进程的必要组成单位. 主线程: 程序开始运行的时候,就产生了一个主线进程来运行这个程序. 子线程: 是由主线程开启的其他线程. · 各线程之间的工 ...

  10. 【学习总结】Git学习-参考廖雪峰老师教程九-使用码云

    学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...