题目链接:https://vjudge.net/problem/HDU-3045

Picnic Cows

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3491    Accepted Submission(s): 1124

Problem Description
It’s summer vocation now. After tedious milking, cows are tired and wish to take a holiday. So Farmer Carolina considers having a picnic beside the river. But there is a problem, not all the cows consider it’s a good idea! Some cows like to swim in West Lake, some prefer to have a dinner in Shangri-la ,and others want to do something different. But in order to manage expediently, Carolina coerces all cows to have a picnic!
Farmer Carolina takes her N (1<N≤400000) cows to the destination, but she finds every cow’s degree of interest in this activity is so different that they all loss their interests. So she has to group them to different teams to make sure that every cow can go to a satisfied team. Considering about the security, she demands that there must be no less than T(1<T≤N)cows in every team. As every cow has its own interest degree of this picnic, we measure this interest degree’s unit as “Moo~”. Cows in the same team should reduce their Moo~ to the one who has the lowest Moo~ in this team——It’s not a democratical action! So Carolina wishes to minimize the TOTAL reduced Moo~s and groups N cows into several teams.
For example, Carolina has 7 cows to picnic and their Moo~ are ‘8 5 6 2 1 7 6’ and at least 3 cows in every team. So the best solution is that cow No.2,4,5 in a team (reduce (2-1)+(5-1) Moo~)and cow No.1,3,6,7 in a team (reduce ((7-6)+(8-6)) Moo~),the answer is 8.
 
Input
The input contains multiple cases.
For each test case, the first line has two integer N, T indicates the number of cows and amount of Safe-base line.
Following n numbers, describe the Moo~ of N cows , 1st is cow 1 , 2nd is cow 2, and so on.
 
Output
One line for each test case, containing one integer means the minimum of the TOTAL reduced Moo~s to group N cows to several teams.
 
Sample Input
7 3
8 5 6 2 1 7 6
 
Sample Output
8
 
Source
 
Recommend
gaojie
 

题意:

有n头牛去野营,烧烤,吃什么,牛肉?细思极恐。不扯了。将这n头牛分成若干组,且每一组至少要有T头。每头牛都有一个值,一个组的值是这个组内,所有牛的值减去最小值的差之和。而总和为所有组的值之和,问:怎样分配,才能使得总和最小?

题解:

1.可得一个结论:尽量把值相近的牛分到同一组。所以首先需要根据值的大小对牛进行排序。然后就是一个区间划分的问题了。

2.由于n<=4e5,O(n^2)DP枚举是会超时的,所以需要利用斜率进行优化。

3.由于题目规定了每一组的个数必须大于等于T,因此需要特别处理:

1) dp值从下标为T开始求,因为1~T-1都不能构成一组,其DP没有意义。

2) 在求得dp[i]之后,不能直接把 i 放进队列中,因为 i 不一定能为i+1、i+2……等作状态转移,因为必须要满足一组个数大于等于T的要求。然而,这个还不是最重要的,如果直接把 i 放进队列,那么因为斜率优化所进行的操作:把认为比 i 劣且在队列里的元素出队了,而这些元素又是往后的状态所必须知道的。因此就出现了错误。

3) 根据2) 我们需要限定:在队列里的元素,必须都是往后状态所能够转移的,相比之下只是优劣问题而已。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int MAXM = 1e5+;
const int MAXN = 4e5+; LL val[MAXN], sum[MAXN], dp[MAXN];
int q[MAXN], head, tail; LL getUp(int j, int k)
{
return (dp[j]-sum[j]) - (dp[k]-sum[k]);
} LL getDown(int j, int k)
{
return j-k;
} LL getDp(int i, int j)
{
return dp[j]+(sum[i]-sum[j])-1LL*(i-j)*val[i];
} int main()
{
int T, n;
while(scanf("%d%d", &n,&T)!=EOF)
{
for(int i = ; i<=n; i++)
scanf("%lld", &val[i]);
sort(val+, val++n);
reverse(val+, val++n); //降序 sum[] = ;
for(int i = ; i<=n; i++)
sum[i] = sum[i-]+val[i]; // O(n^2)的写法:
// for(int i = T; i<=n; i++)
// {
// dp[i] = sum[i]-i*val[i];
// for(int j = T; j<=i-T; j++)
// dp[i] = min(dp[i], dp[j]+sum[i]-sum[j]-1LL*(i-j)*val[i]);
// } head = tail = ;
dp[] = ;
q[tail++] = ;
for(int i = T; i<=n; i++) //从T开始,因为前面的都无效
{
while(head+<tail && getUp(q[head+],q[head])<=
-1LL*getDown(q[head+],q[head])*val[i]) head++;
dp[i] = getDp(i, q[head]); int j = i-T+; //加入对从下一个开始有效的状态,而i-T+1对i+1、i+2……有效
if(j<T) continue; //只有j>=T, j才有效,能转移状态
while(head+<tail && 1LL*getUp(j, q[tail-])*getDown(q[tail-],q[tail-])<=
1LL*getUp(q[tail-],q[tail-])*getDown(j, q[tail-])) tail--;
q[tail++] = j;
}
printf("%I64d\n", dp[n]);
}
}

错误写法:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int MAXM = 1e5+;
const int MAXN = 1e3+; int val[MAXN], sum[MAXN], dp[MAXN];
int q[MAXN], head, tail; int getUp(int i, int j)
{
return dp[i] - dp[j];
} int getDown(int i, int j)
{
return sum[i] - sum[j];
} int getDp(int i, int j)
{
return dp[j] + (sum[i]-sum[j]+)*val[i];
} int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
sum[] = ;
for(int i = ; i<=n; i++)
scanf("%d%d", &sum[i],&val[i]), sum[i] += sum[i-]; dp[] = ;
head = tail = ;
q[tail++] = ;
for(int i = ; i<=n; i++)
{
while(head+<tail && getUp(q[head+],q[head])<=getDown(q[head+],q[head])*val[i]) head++;
dp[i] = getDp(i, q[head]);
/*
直接把i加进去为何错误?因为i的存在不能为i+1的转移作贡献,本来放着没什么关系的,
关键是i加进去的时候,还可能会把前面的去掉,这样就有可能把能为i+1转移的去掉了。
所以,加进队列的应该是那些能为往后所有状态转移的。
*/
while(head+<tail && getUp(i, q[tail-])*getDown(q[tail-],q[tail-])<=
getUp(q[tail-],q[tail-])*getDown(i, q[tail-])) tail--;
q[tail++] = i;
}
printf("%d\n", dp[n]);
}
}

HDU3045 Picnic Cows —— 斜率优化DP的更多相关文章

  1. hdu 3045 Picnic Cows(斜率优化DP)

    题目链接:hdu 3045 Picnic Cows 题意: 有n个奶牛分别有对应的兴趣值,现在对奶牛分组,每组成员不少于t, 在每组中所有的成员兴趣值要减少到一致,问总共最少需要减少的兴趣值是多少. ...

  2. HDU 3045 Picnic Cows(斜率优化DP)

    Picnic Cows Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  3. POJ2018 Best Cow Fences —— 斜率优化DP

    题目链接:https://vjudge.net/problem/POJ-2018 Best Cow Fences Time Limit: 1000MS   Memory Limit: 30000K T ...

  4. 【转】斜率优化DP和四边形不等式优化DP整理

    (自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...

  5. bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

    题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...

  6. bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

    题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...

  7. [BZOJ3156]防御准备(斜率优化DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP

  8. 【BZOJ-1096】仓库建设 斜率优化DP

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3719  Solved: 1633[Submit][Stat ...

  9. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

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

随机推荐

  1. 【前端学习笔记】ajax与php之间的互动

    ajax通常会牵扯到跨域问题,所以我们通常的解决方案是,通过ajax将参数传到后台php文件中 在后台通过php文件进行跨域访问api,再将结果返回到ajax响应中.需要注意一下几点: 1.可以通过& ...

  2. day02-菜单处理

    解决力度到按钮的级别 ----------------------------------------------------------------------------------------- ...

  3. uva 10090 二元一次不定方程

    Marbles Input: standard input Output: standard output I have some (say, n) marbles (small glass ball ...

  4. Netflix Ribbon源码设计错误的证据(附正确示例)

    我在之前一篇博客里https://www.cnblogs.com/yangfeiORfeiyang/p/9644254.html 里对Netflix Ribbon的Loadbalancer类源码设计的 ...

  5. hdu4619 / 最大独立集

    题意,一个矩阵,上面可以横放或者竖着放骨牌(1X2)保证横的与横的不重叠,竖的和竖的不重叠,求拿掉最小的牌,使所有的都不重叠. 分析:一看,不重叠就是没有边,拿最少,就是留最多,最大独立集啊!二分图, ...

  6. webstorm调试(一)提示css未使用的选择器Selector is never used

    一.css未使用的选择器Selector 今天写vue的时候,给动态绑定了一个class属性,然后样式里面就给了warning,看起来怪怪的,很不舒服

  7. ubuntu下安装翻译软件

    原文: http://sixipiaoyang.blog.163.com/blog/static/6232358820144146386437/ Ubuntu下常用的翻译软件有StarDict,Gol ...

  8. Hbase优化总结

    1.JVM参数优化: –Xmn=12G –Xms=24G  -Xmx=24G  根据实际机器情况调整,一般为整个机器内存的一半,同时建议regionServer的堆内存建议不要超过32G ; -XX: ...

  9. 揭秘jbpm流程引擎内核设计思想及构架

    揭秘jbpm流程引擎内核设计思想及构架 作者 胡长城(银狐999)   1     前言 2     阅读本篇的基础准备 2.1      概念的基础 2.2      环境的基础 3     什么是 ...

  10. CSS - 如何实现强制不换行、自动换行、强制换行

    来源:http://www.cnblogs.com/mcat/p/4884644.html 强制不换行 div{ white-space:nowrap; } 自动换行 div{ word-wrap: ...