K - 摩天轮

Time Limit: 10000/4000MS (Java/Others)     Memory Limit: 262143/262143KB (Java/Others)
Submit Status

一天,冬马被春希和雪菜拉着去一起去游乐园玩。

经过了各种过山车的洗礼后,三人决定去坐摩天轮休息下。

这是一个巨大的摩天轮,每一个车厢能坐任意多的人。现在,等着坐摩天轮的有n个人(包含他们3人),摩天轮还有m个车厢可以坐人。每个人都有自己肥胖程度,出于某些原因,胖子和瘦子坐在同一节车厢就会产生一定的矛盾,这个矛盾的值为(MAX−MIN)2,其中MAX为当前车厢里面最胖的人的肥胖程度,MIN为最廋的那个人的肥胖程度。

爱管闲事的春希当然不希望就因为这点小事而使大家的这趟旅途不愉快,于是他决定帮大家安排怎么坐才能使总的矛盾值最小,希望你能帮他找到这个最小的矛盾值

Input

第一行为两个整数n,m,分别表示人数和车厢数。(3≤n≤10000,1≤m≤5000)

第二行为n个整数,wi表示第i个人的肥胖程度。(0≤wi≤1000000)

Output

每组数据,输出一个整数,为矛盾的最小值。(答案保证小于231)

Sample input and output

Sample Input Sample Output
4 2
4 7 10 1
18

解题思路:

这是一道斜率优化DP的题目.

我们令 f ( i , j ) 表示将前 i 个人分成 j 份所需的最小费用.

F ( i , j ) = min{ F ( u , j -1) + (sum[i] – sum[ u + 1])^2 }

但是这样做的复杂度高达O(N^2*M),对于本题的规模来讲无法承受,我们考虑

K1 < k2 < i ,且 k2 比 k1更优

有式子

F ( k2 , j - 1 ) + sum( k2 ) ^ 2 -  F( k1 , j -1 ) – sum(k1+1) ^ 2

————————————————————— —————————————   < 2 * sum(i)

sum ( k2 ) – sum( k1+1)

显然这是一个斜率的式子.

假设现在 K(k1 – k2) < 2*sum[i] ,那么k1这个点还有价值吗?

我们注意到sum[i]是单调不减的,也就是说,对于之后的i2,i3…..

K(k1 – k2) < 2*sum[i_x] ,也就是说,k1 完全不可能成为某个点的最优解了,是可以舍弃的.

那么如果现在有 K(k1 – k2) >= 2*sum[i]呢,目前显然是选择k1比k2好,我们应不应该舍弃k2呢?答案是不应该,因为随着i的增大,sum[i]是不减的(也就是说,sum[i]可能会增大),此时 K(k1 – k2) < 2*sum[i] 是可能成立的.

综上所述,我们维护一个单调队列即可,只不过这个单调队列剔除 / 加入元素的条件都是和与斜率有关,这样我们可以在O(1)的时间内得到某个点的最优决策点,复杂度成功降到了O(n*m).

代码使用了滚动数组进行优化

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e4 + ;
int n,m,h[maxn],f[][maxn],cur=,q[maxn]; double slope(int x,int y)
{
if (h[x+] == h[y+])
return 1e233;
return (double)(f[cur^][x] + h[x+]*h[x+] - (f[cur^][y] + h[y+]*h[y+])) / (double)(h[x+] - h[y+]);
} int main(int argc,char *argv[])
{
scanf("%d%d",&n,&m);
for(int i = ; i <= n ; ++ i) scanf("%d",&h[i]);sort(h+,h++n);
for(int i = ; i <= n ; ++ i) f[cur][i] = (h[i]-h[])*(h[i]-h[]);
for(int i = ; i <= m ; ++ i)
{
cur ^= ;
int front = , rear = ;
q[rear++] = ;
for(int j = ; j <= n ; ++ j)
{
while (rear - front > && slope(q[front],q[front+]) <= *h[j])
front++;
f[cur][j] = f[cur^][q[front]] + (h[j] - h[q[front]+])*(h[j] - h[q[front]+]);
while(rear - front > && slope(q[rear-],q[rear-]) >= slope(q[rear-],j))
rear--;
q[rear++] = j;
}
}
printf("%d\n",f[cur][n]);
return ;
}

UESTC_摩天轮 2015 UESTC Training for Dynamic Programming<Problem K>的更多相关文章

  1. UESTC_导弹拦截 2015 UESTC Training for Dynamic Programming<Problem N>

    N - 导弹拦截 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  2. UESTC_最少花费 2015 UESTC Training for Dynamic Programming<Problem D>

    D - 最少花费 Time Limit: 30000/10000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  3. UESTC_酱神寻宝 2015 UESTC Training for Dynamic Programming<Problem O>

    O - 酱神寻宝 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  4. UESTC_酱神的旅行 2015 UESTC Training for Dynamic Programming<Problem M>

    M - 酱神的旅行 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit ...

  5. UESTC_菲波拉契数制升级版 2015 UESTC Training for Dynamic Programming<Problem L>

    L - 菲波拉契数制升级版 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Su ...

  6. UESTC_男神的约会 2015 UESTC Training for Dynamic Programming<Problem J>

    J - 男神的约会 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit ...

  7. UESTC_邱老师选妹子(二) 2015 UESTC Training for Dynamic Programming<Problem I>

    I - 邱老师选妹子(二) Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Su ...

  8. UESTC_邱老师选妹子 2015 UESTC Training for Dynamic Programming<Problem H>

    H - 邱老师选妹子 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  9. UESTC_邱老师玩游戏 2015 UESTC Training for Dynamic Programming<Problem G>

    G - 邱老师玩游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

随机推荐

  1. SEO的URL如何优化才是最佳

    原文地址:http://www.chinaz.com/web/2007/0413/6841.shtml 很多人都知道URL对SEO的重要之处,但是很多站点却忽略了站点的路径优化.今天本人在这里写几点关 ...

  2. Populating Next Right Pointers in Each Node II 解答

    Question Follow up for problem "Populating Next Right Pointers in Each Node". What if the ...

  3. Codeforces243C-Colorado Potato Beetle(离散化+bfs)

    Old MacDonald has a farm and a large potato field, (1010 + 1) × (1010 + 1) square meters in size. Th ...

  4. if switch练习(体重)

    public class shencai { public static void main(String[] args) { int h= 186,g= 80; String Sex = " ...

  5. SQL Server,Oracle,DB2索引建立语句的对比

    原文引至:http://jvortex.blog.163.com/blog/static/16961890020122141010878/ 我们知道,索引是用于加速数据库查询的数据库对象.原理就是减少 ...

  6. Java连接Oracle数据库的示例代码

    最基本的Oracle数据库连接代码(只针对Oracle11g): 1.右键项目->构建路径 ->配置构建路径,选择第三项“库”,然后点击“添加外部Jar”,选择 “D:\Oracle\ap ...

  7. uva 1291(dp)

    题意:有一台跳舞机,中间是0.上左下右分别代表1 2 3 4,初始状态人站在中间.两仅仅脚都踏在0上,然后给出一段序列以0为结束,要按顺序踩出来,从0踏到四个方向须要消耗2点能量,从一个方向到相邻的方 ...

  8. 同一DataTable下创建多个结构数据相同的DataView的小问题

    昨天在根据经理的要求修改公司后台的时候,遇到了一个很奇怪的问题 DataView dvFocus = ]); DataView dvLook = ]); DataView dvNewUser = ]) ...

  9. Windows - 远程桌面无证书

    可以从命令行启动远程桌面,输入:mstsc /v:地址:端口 /admin

  10. PHP学习笔记三十四【记录日志】

    <?php function my_error2($errno,$errmes) { echo "错误号:".$errno; //默认时区是格林威治相差八个时区 //设置 1 ...