hdu3480

给定一个有n个数的集合,将这个集合分成m个子集,要求子集的并等于全集
求花费最小。

花费为该子集的(最大数-最小数)的平方。

我们将n个数排序,

a < b < c < d

那么不可能a,c一个集合,b,c一个集合

明显a,b一个集合,c,d一个集合更优

也就是说某一个数只能和它前面的连续几个数合起来形成一个子集。 正是因为有这个性质才能dp

dp[i][j]表示第j个数在第i个集合的最小花费

dp[i][j] = min(dp[i][j],dp[i-1][k]) 1<=k<j

dp[i-1][k1] + (a[j]-a[k1+1])^2 < dp[i-1][k2]+(a[j]-a[k2+1])^2

dp[i-1][k1]+a[k1]^2-(dp[i-1][k2]+a[k2]^2) < 2a[j]*(a[k1+1]-a[k2+1])

这样就能够用斜率优化了,由于是求最小值,所以维护一个下凸包就行了。

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef int LL;
const int INF = <<;
/*
给定一个有n个数的集合,将这个集合分成m个子集,要求子集的并等于全集
求花费最小, 花费为什么每个集合的(最大值-最小值)的平方 dp[i][j]表示第j个数在第i个集合的最小花费
用滚动数组压缩空间
*/ const int N = + ;
const int M = + ;
LL a[N];
LL dp[][N];
int q[N], head, tail;
LL dw(LL a, LL b)
{
return (a - b)*(a - b);
}
LL getUp(int k1, int k2, int c)
{
return dp[c][k1] + a[k1 + ] * a[k1 + ] - (dp[c][k2] + a[k2 + ] * a[k2 + ]);
}
LL getDown(int k1, int k2)
{
return * (a[k1 + ] - a[k2 + ]);
}
int main()
{
int t, n, m;
scanf("%d", &t);
for (int k = ; k <= t; ++k)
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i)
scanf("%d", &a[i]);
sort(a + , a + n + );
n = unique(a + , a + n + ) - a - ;
if (m > n)
m = n;
int c = ;
for (int j = ; j <= n; ++j)
dp[][j] = dw(a[j], a[]);
for (int i = ; i <= m; ++i)
{
head = tail = ;
for (int j = i; j <= n; ++j)
{
while (head + < tail && getUp(j - , q[tail - ], c)*getDown(q[tail - ], q[tail - ])
<= getUp(q[tail - ], q[tail - ], c)*getDown(j - , q[tail - ]))
tail--;
q[tail++] = j - ;
while (head + < tail&&getUp(q[head + ], q[head], c) < a[j] * getDown(q[head+], q[head]))
head++;
dp[c ^ ][j] = dp[c][q[head]] + dw(a[j], a[q[head] + ]);
}
c ^= ;
}
printf("Case %d: %d\n",k, dp[c][n]);
}
return ;
}

hdu3405

n头牛,分成几组,每组至少有k头牛
要求费用最小,

费用是每组所有牛的moo,减去该组中最小的moo

将moo排序

那么如果是分成两组的话,那么不可能是a,c一组, b,d一组
a,b,一组比c,d一组肯定更优。
又遇到了有这种性质的题目, 连续比交叉更优,这样,才能用dp来解决,

dp[j]表示以j结尾的team的最小花费
(dp[k1]-sum[k1]+k1*moo[k1+1]) - (dp[k2]-sum[k2]+k2*moo[k2+1]) < i*(moo[k1+1]-moo[k2+1])
dp[k1]+k1*moo[k1+1] - (dp[k2]+k2*moo[k2+1]) < i * (moo[k1+1]-moo[k2+1])
所以维护递增的斜率

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef __int64 LL;
const int INF = <<;
/*
n头牛,分成几组,每组至少有k头牛
要求费用最小,
费用是每组所有牛的moo,减去该组中最小的moo
a < b < c < d
那么如果是分成两组的话,那么不可能是a,c一组, b,d一组
a,b,一组比c,d一组肯定更优。
又遇到了有这种性质的题目, 连续比交叉更优,这样,才能用dp来解决,
dp[j]表示以j结尾的team的最小花费
(dp[k1]-sum[k1]+k1*moo[k1+1]) - (dp[k2]-sum[k2]+k2*moo[k2+1]) < i*(moo[k1+1]-moo[k2+1])
dp[k1]+k1*moo[k1+1] - (dp[k2]+k2*moo[k2+1]) < i * (moo[k1+1]-moo[k2+1])
所以维护递增的斜率 */
const int N = + ;
LL moo[N], dp[N], sum[N];
int q[N], head, tail; LL getUp(int k1, int k2)
{
return dp[k1] + k1*moo[k1 + ] - sum[k1] - (dp[k2] + k2*moo[k2 + ] - sum[k2]);
}
LL getDown(int k1, int k2)
{
return moo[k1 + ] - moo[k2 + ];
}
int main()
{
int n, t;
while (scanf("%d%d", &n, &t) != EOF)
{
for (int i = ; i <= n; ++i)
{
scanf("%I64d", &moo[i]);
}
sort(moo + , moo + n + );
for (int i = ; i <= n; ++i)
sum[i] = moo[i] + sum[i - ];
for (int i = t; i <= n; ++i)
dp[i] = sum[i] - i*moo[]; head = tail = ;
q[tail++] = ;
q[tail++] = t;
int k = t + ;
for (int i = *t; i <= n; ++i)
{
while (head + < tail&&getUp(q[head + ], q[head]) < i*getDown(q[head + ], q[head]))
head++;
dp[i] = dp[q[head]] + sum[i]-sum[q[head]] - (i-q[head])*moo[q[head] + ];
while (head + < tail&&getUp(k, q[tail - ])*getDown(q[tail - ], q[tail - ]) <= getUp(q[tail - ], q[tail - ])*getDown(k, q[tail - ]))
tail--;
q[tail++] = k++;
}
printf("%I64d\n", dp[n]);
}
return ;
}

一类斜率优化的dp(特有性质:只能连续,不能交叉)的更多相关文章

  1. 队列优化和斜率优化的dp

    可以用队列优化或斜率优化的dp这一类的问题为 1D/1D一类问题 即状态数是O(n),决策数也是O(n) 单调队列优化 我们来看这样一个问题:一个含有n项的数列(n<=2000000),求出每一 ...

  2. [NOI2014]购票 --- 斜率优化 + 树形DP + 数据结构

    [NOI2014]购票 题目描述 今年夏天,NOI在SZ市迎来了她30周岁的生日. 来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每 ...

  3. Luogu P5468 [NOI2019]回家路线 (斜率优化、DP)

    题目链接: (luogu) https://www.luogu.org/problemnew/show/P5468 题解: 爆long long毁一生 我太菜了,这题这么简单考场上居然没想到正解-- ...

  4. [bzoj 2726] 任务安排 (斜率优化 线性dp)

    3月14日第三题!!!(虽然是15号发的qwq) Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3-N.这N个任务被分成若干批 ...

  5. 斜率优化DP讲解

    对于斜率优化的DP转移方程,一般以w[i]=max(w[j]+(sum[i]-sum[j])*v)的1D1D形式为主,直观看来就是前j个为若干个阶段,第j+1到第i个为一个阶段,每个阶段有自己的代价或 ...

  6. 【BZOJ-1597】土地购买 DP + 斜率优化

    1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2931  Solved: 1091[Submit] ...

  7. [HNOI2008]玩具装箱TOY --- DP + 斜率优化 / 决策单调性

    [HNOI2008]玩具装箱TOY 题目描述: P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京. 他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器 ...

  8. DP玄学优化——斜率优化

    --以此博客来悼念我在\(QBXT\)懵逼的时光 \(rqy\; tql\) (日常%\(rqy\)) 概念及用途 斜率优化是\(DP\)的一种较为常用的优化(据说在高中课本里稍有提及),它可以用于优 ...

  9. DP斜率优化学习笔记

    斜率优化 首先,可以进行斜率优化的DP方程式一般式为$dp[i]=\max_{j=1}^{i-1}/\min_{j=1}^{i-1}\{a(i)*x(j)+b(i)*y(j)\}$ 其中$a(j)$和 ...

随机推荐

  1. 使用微软Remote Desktop 手机远程控制 windows

    在我的电脑上右击选择“属性”,打开属性面板.然后点击左边的“远程设置”. 2/2 如果你要操作的计算机出入外网(大多数是家里网线进线直连电脑),就选择远程桌面选择框中的“允许运行任意版本远程桌面的计算 ...

  2. ZeroMQ:云计算时代最好的通讯库

    还在学socket编程吗?还在研究为什么epoll比select更好吗? 噢,不必了! 在复杂的云计算环境中,我们面临的难题远比这个复杂得多. 庞大的服务器集群作为计算云,对来来看或许只是一个简单的搜 ...

  3. 设置程序版本等信息(可直接修改pro文件设置,但是更推荐使用rc文件设置)

    Qt版本:5.2.0 在.pro文件中设置版本等信息 VERSION = 1.2.3 QMAKE_TARGET_PRODUCT = 产品名称QMAKE_TARGET_COMPANY = 公司QMAKE ...

  4. DLL五篇

    http://www.cnblogs.com/NeuqUstcIim/archive/2009/01/12/1374511.htmlhttp://www.cnblogs.com/NeuqUstcIim ...

  5. Lisp的永恒之道 好文

    http://www.cnblogs.com/weidagang2046/archive/2012/06/03/tao_of_lisp.html

  6. 15个最好的HTML5前端响应式框架(2014)

    文中的多个框架基于SASS创建,SCSS是一种比LESS更简洁的样式表编程语言,它能够编绎成CSS,可复用CSS代码,声明变量,甚至是函数,类Ruby/Python的语法.參见: LESS vs SA ...

  7. 【PostgreSQL】PostgreSQL语法

    在阅读的过程中有不论什么问题.欢迎一起交流 邮箱:1494713801@qq.com    QQ:1494713801 一.PostgreSQL时间类型转换 --时间类型转成字符类型 select t ...

  8. 基于Qt的类QQ气泡聊天的界面开发

    近期在写IM 聊天界面,想设计出一个类似QQ气泡聊天的样式 使用了几种办法 1:使用Qt以下的QListview来实现QQ类似效果.差强人意 2:使用QWebview载入html css样式来完毕.发 ...

  9. Cocos2d-x 游戏存档

    游戏存档功能能够保存游戏中数据.让玩家游戏能够延续. 单机游戏更为重要.而CCUserDefault能够作轻量级数据库使用,用来存储数据,支持数据类型bool,int, float, double, ...

  10. Java Word Ladder(字梯)

    问题: Given two words (start and end), and a dictionary, find the length of shortest transformation se ...