(Relax 数论1.21)POJ 3258 River Hopscotch
2013-11-23 10:42
295 查看
本题的分析参考了http://blog.csdn.net/lyy289065406/article/details/6648558
大致题意:
一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L。
河中有n块石头,每块石头到S都有唯一的距离
问现在要移除m块石头(S和E除外),每次移除的是与当前最短距离相关联的石头,要求移除m块石头后,使得那时的最短距离尽可能大,输出那个最短距离。
解题思路:
经典的二分,理解题意就不怎么难了 (其实编程不难,要理解就非常难。。。。)
详细的解释看我的程序,实在看不懂就参考一下我POJ3273的做法,看上去不同,几时思路是差不多的,数学题都很难理解的,耐心吧。。。。
我感觉说了好像没说的感觉\(^o^)/~ 总之看程序吧
/*
* POJ_3258.cpp
*
* Created on: 2013年11月23日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 50005;
int dist[maxn];
int l, n, m;
int main() {
while (scanf("%d%d%d", &l, &n, &m) != EOF) {
int low = l;//上界(一次跳跃的最短距离)
int high = l;//下界(一次跳跃的最大距离)
dist[0] = 0;//起点S
dist[n + 1] = l; //终点E
int i;
for (i = 1; i <= n + 1; ++i) {
if (i <= n) {//仅输入1~n
scanf("%d", &dist[i]);
}
if (low > dist[i] - dist[i - 1]) {
low = dist[i] - dist[i - 1];
}
}
sort(dist, dist + n + 2);
while (low <= high) {
int mid = (low + high) / 2;//对最大跳和最小跳的距离折中,二分查找mid相对于最优解是偏大还是偏小
int deleterock = 0;
int sum = 0;
//假设mid是移除m个石头后的最短距离
for (i = 1; i <= n + 1; ++i) {
if ((sum += dist[i] - dist[i - 1]) <= mid) {
deleterock++;
} else {//当从第i个距离累加到i+k个距离后,若sum>mid,则k个距离作为一段
sum = 0; //sum置0,从第i+k+1个距离重新累加
}
}
if (deleterock <= m) {//本题难点之一:即使delrock==m也不一定找到了最优解
low = mid + 1;//用当前mid值移除的石头数小于规定数,说明mid偏小
} else {
high = mid - 1;
}
}
printf("%d\n", low);
}
return 0;
}
大致题意:
一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L。
河中有n块石头,每块石头到S都有唯一的距离
问现在要移除m块石头(S和E除外),每次移除的是与当前最短距离相关联的石头,要求移除m块石头后,使得那时的最短距离尽可能大,输出那个最短距离。
解题思路:
经典的二分,理解题意就不怎么难了 (其实编程不难,要理解就非常难。。。。)
详细的解释看我的程序,实在看不懂就参考一下我POJ3273的做法,看上去不同,几时思路是差不多的,数学题都很难理解的,耐心吧。。。。
我感觉说了好像没说的感觉\(^o^)/~ 总之看程序吧
/*
* POJ_3258.cpp
*
* Created on: 2013年11月23日
* Author: Administrator
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 50005;
int dist[maxn];
int l, n, m;
int main() {
while (scanf("%d%d%d", &l, &n, &m) != EOF) {
int low = l;//上界(一次跳跃的最短距离)
int high = l;//下界(一次跳跃的最大距离)
dist[0] = 0;//起点S
dist[n + 1] = l; //终点E
int i;
for (i = 1; i <= n + 1; ++i) {
if (i <= n) {//仅输入1~n
scanf("%d", &dist[i]);
}
if (low > dist[i] - dist[i - 1]) {
low = dist[i] - dist[i - 1];
}
}
sort(dist, dist + n + 2);
while (low <= high) {
int mid = (low + high) / 2;//对最大跳和最小跳的距离折中,二分查找mid相对于最优解是偏大还是偏小
int deleterock = 0;
int sum = 0;
//假设mid是移除m个石头后的最短距离
for (i = 1; i <= n + 1; ++i) {
if ((sum += dist[i] - dist[i - 1]) <= mid) {
deleterock++;
} else {//当从第i个距离累加到i+k个距离后,若sum>mid,则k个距离作为一段
sum = 0; //sum置0,从第i+k+1个距离重新累加
}
}
if (deleterock <= m) {//本题难点之一:即使delrock==m也不一定找到了最优解
low = mid + 1;//用当前mid值移除的石头数小于规定数,说明mid偏小
} else {
high = mid - 1;
}
}
printf("%d\n", low);
}
return 0;
}
相关文章推荐
- 【贪心专题】POJ 3258 River Hopscotch (最大化最小值 贪心+二分搜索)
- POJ 3258 River Hopscotch
- River Hopscotch(POJ--3258【二分查找】
- poj 3258-River Hopscotch
- POJ 3258 River Hopscotch(二分法搜索)
- poj 3258 River Hopscotch(二分+贪心)
- poj 3258 River Hopscotch(二分法,最小值最大化)
- (Relax 数论1.20)POJ 3273 Monthly Expense(经典二分)
- (Relax 数论1.6)POJ 1061 青蛙的约会(扩展的欧几里得公式)
- POJ 3258 River Hopscotch
- [二分+贪心] POJ 3258 River Hopscotch
- poj 3258 二分 River Hopscotch
- POJ 3258 River Hopscotch(二分·最小距离最大)
- poj 3258 River Hopscotch(二分答案)
- poj 3258 River Hopscotch(二分法,最小值最大化)
- 【POJ】[3258]River Hopscotch
- POJ 3258 River Hopscotch(二分)
- POJ 3258 River Hopscotch(最大化最小值)
- 【poj 3258】 River Hopscotch
- POJ 3258--River Hopscotch