HDU3480-Division-斜率dp
首先想到的就是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的更多相关文章
- HDU3480 Division —— 斜率优化DP
题目链接:https://vjudge.net/problem/HDU-3480 Division Time Limit: 10000/5000 MS (Java/Others) Memory ...
- HDU 3480 - Division - [斜率DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- hdu3480 Division(dp平行四边形优化)
题意:将n个数分成m段,每段的代价为最大值减最小值的平方,为代价最小是多少n<=10000 ,m<=5000 题解:先拍好序,从小到大,这样绝对是花费最小的,不过怎么样来做呢?一定很容易想 ...
- [kuangbin带你飞]专题二十 斜率DP
ID Origin Title 20 / 60 Problem A HDU 3507 Print Article 13 / 19 Problem B HDU 2829 Lawr ...
- bzoj4518: [Sdoi2016]征途--斜率DP
题目大意:把一个数列分成m段,计算每段的和sum,求所有的sum的方差,使其最小. 由方差*m可以化简得ans=m*sigma(ki^2)-sum[n]^2 很容易得出f[i][j]=min{f[i- ...
- hdu 3507 斜率dp
不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个 ...
- 斜率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] * ...
- 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] ...
- 斜率DP题目
uva 12524 题意:沿河有n个点,每个点有w的东西,有一艘船从起点出发,沿途可以装运东西和卸载东西,船的容量无限,每次把wi的东西从x运到y的花费为(y-x)*wi; 问把n个点的东西合并成k个 ...
- bzoj 3156 防御准备(斜率DP)
3156: 防御准备 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 837 Solved: 395[Submit][Status][Discuss] ...
随机推荐
- mysql及python交互
mysql在之前写过一次,那时是我刚刚进入博客,今天介绍一下mysql的python交互,当然前面会把mysql基本概述一下. 目录: 一.命令脚本(mysql) 1.基本命令 2.数据库操作命令 3 ...
- IDEA报错Error:Module 'shop-common' production: java.lang.IndexOutOfBoundsException
问题描述: 本来项目是正常的,编译.运行.启动都是OK的,但是在一次电脑重启后,出现了以上这个问题:Error:Module 'shop-common' production: java.lang.I ...
- python第七章:常用模块--小白博客
yagmail模块 python标准库中发送电子邮件的模块比较复杂,因此,有许多开原的库提供了更加易用的接口来发送电子邮件,其中yagmail是一个使用比较广泛的开原项目,yagmail底层依然使用了 ...
- 二十二:制作app的时候超出部分不能滑动
给需要滑动的区域写以下样式(父级是浏览器) position: absolute; left: 0; right: 0; bottom: 0; top: 0; overflow-x: hidden; ...
- Python-os模块-60
os 模块: 和操作系统打交道的模块 os模块是与操作系统交互的一个接口 os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirna ...
- HDU - 4027 线段树减枝
这题太坑了...满满的都是坑点 1号坑点:给定左右区间有可能是反的...因为题目上说x,y之间,但是没有说明x,y的大小关系(害我一直RE到怀疑人生) 2号坑点:开根号的和不等于和开根号(还好避开了) ...
- Diverse Garland CodeForces - 1108D (贪心+暴力枚举)
You have a garland consisting of nn lamps. Each lamp is colored red, green or blue. The color of the ...
- 【转】shell之for、while、until循环
一.简介 Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for.while和until.while循环和for循环属于“当型循环”,而unti ...
- MySQL 优化集锦
case 1: 如果筛选or条件有多个的时候,应该将最好判断的放在最前面,将最不好判断的放在最后面 比如,有一个学生表,想要找出其中年龄是20岁,住址中包含666这个数字的记录.可以下面这两个方案: ...
- php之常用扩展总结
在此总结,开发中经常使用到的扩展,来进行日常PHP的开发工作 bcmath(精确数值处理) bz2 calendar Core ctype curl date dom ereg exif filein ...