题目链接: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. 洛谷P2365 任务安排 [解法一]

    题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti.在每批任务开始 ...

  2. 解决三星 BIOS 模式没有 Fast Bios Mode选项 U盘动项问题

    今天想分下盘,进入biso竟然没有网上说 Fast Bios Mode选项,最后自己误打误撞竟然设置成功了,太不可思议了官方这么说:开机按F2进入BIOS设置,找到Boot选项下Boot Device ...

  3. ROS安装环境配置及多版本的切换

    环境配置: 为方便起见,我们可以在每次打开终端时让系统自动配置好ROS环境变量,方法如下: echo "source /opt/ros/hydro/setup.bash" > ...

  4. Codeforces 375 D Tree and Queries

    Discription You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. ...

  5. 自己动手实现浏览器,21天自制chromium:起手篇

    转:https://zhuanlan.zhihu.com/p/29101613?utm_medium=social&utm_source=qq 大家好,我又来了.这篇是21天自制原子弹的姐妹篇 ...

  6. PPT中的图像失真

    现象:Office PowerPoint 保存出来的PPT文件在WPS下播放的时候会出现图像失真的显现. 解决方法:Office PowerPoint打开PPT将里面的图像另存为BMP格式的图像文件, ...

  7. 【转载】云计算的三种服务模式:IaaS,PaaS和SaaS

    一张图就看懂了.其他的都不用说了. 原文:http://blog.csdn.net/hjxgood/article/details/18363789

  8. svm、logistic regression对比

    相同点:都是线性分类算法 不同点: 1.损失函数不同 LR:基于“给定x和参数,y服从二项分布”的假设,由极大似然估计推导 SVM: hinge loss + L2 regularization的标准 ...

  9. 关于android 使用bitmap的OOM心得和解决方式

    android开发,从2010年開始学习到如今的独立完毕一个app,这漫长的四年,已经经历了非常多次bug的折磨.无数次的加班训练.然而,自以为自己已经比較了解android了,却近期在一个项目上.由 ...

  10. 说说怎样管理软件日常执行的server

    大家应该都有这种情况.就是软件开发时都是全力以赴的把软件开发出来.一旦软件上线执行起来我们就能松口气.从而放松了对server及数据的管理.往往这个时候.server的一个小故障都能让我们忙上好一阵. ...