poj3258——二分优化

poj3258——二分优化

River Hopscotch

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 8201   Accepted: 3531

Description

Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at the end, L units away from the start (1 ≤ L ≤ 1,000,000,000). Along the river between the starting and ending rocks, N (0 ≤ N ≤ 50,000) more rocks appear, each at an integral distance Di from the start (0 < Di < L).

To play the game, each cow in turn starts at the starting rock and tries to reach the finish at the ending rock, jumping only from rock to rock. Of course, less agile cows never make it to the final rock, ending up instead in the river.

Farmer John is proud of his cows and watches this event each year. But as time goes by, he tires of watching the timid cows of the other farmers limp across the short distances between rocks placed too closely together. He plans to remove several rocks in order to increase the shortest distance a cow will have to jump to reach the end. He knows he cannot remove the starting and ending rocks, but he calculates that he has enough resources to remove up to rocks (0 ≤ M ≤ N).

FJ wants to know exactly how much he can increase the shortest distance *before* he starts removing the rocks. Help Farmer John determine the greatest possible shortest distance a cow has to jump after removing the optimal set of M rocks.

Input

Line 1: Three space-separated integers: LN, and M 
Lines 2..N+1: Each line contains a single integer indicating how far some rock is away from the starting rock. No two rocks share the same position.

Output

Line 1: A single integer that is the maximum of the shortest distance a cow has to jump after removing M rocks

Sample Input

25 5 2
2
14
11
21
17

Sample Output

4

Hint

Before removing any rocks, the shortest jump was a jump of 2 from 0 (the start) to 2. After removing the rocks at 2 and 14, the shortest required jump is a jump of 4 (from 17 to 21 or from 21 to 25).

题意:一些石头排成一条线,第一个和最后一个不能去掉,其余的共可以去掉m块,要使去掉后石头间距的最小值最大

思路:和poj3273几乎完全一样,一样的二分,一样的利用两个i,j指针进行贪心判断,不过二分时要注意的是poj3273中mid=(low+high)/2,而这里mid=(low+high)/2+1,因为这里是找最大的,(2+3)/2=2,而不是等于3或2.5,如果这里没有+1,会死循环。

/**
 * start at 16:40
 * end at 17:21
 * time: 41 min
 * problem: poj3258
 *
 */

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>

using namespace std;

typedef long long ll;
const int maxn=1000100;
const ll INF=(1LL<<60);

ll L;
int N,M;
ll pos[maxn];

//int times=1;

bool judge(ll limit)
{
    //cout<<times++<<endl;
    int del_cnt=0;
    for(int i=0,j=1;j<=N+1;j++){ ///用i和j指针控制贪心
        if(pos[j]-pos[i]<limit) del_cnt++;
        else i=j;
    }
    if(del_cnt<=M) return true;
    return false;
}

ll BinSearch(ll low,ll high)
{
    while(low<high){
        ll mid=(low+high)/2+1;///下面是low=mid,所以这里+1,如果下面是high=mid,则不用+1。因为(2+3)/2=2,而不是等于3或2.5,,此处的处理避免死循环
        //cout<<low<<" "<<high<<" "<<mid<<endl;
        if(judge(mid)) low=mid;
        else high=mid-1;
    }
    return low;
}

int main()
{
    while(scanf("%lld%d%d",&L,&N,&M)!=EOF){
        pos[0]=0;
        pos[N+1]=L;
        for(int i=1;i<=N;i++) scanf("%lld",&pos[i]);
        sort(pos,pos+N+1);
        //for(int i=0;i<=N+1;i++) cout<<i<<" "<<pos[i]<<endl;
        ll Min=INF;
        for(int i=1;i<=N+1;i++){
            if(pos[i]-pos[i-1]<Min) Min=pos[i]-pos[i-1];
        }
        //cout<<Min<<endl;
        printf("%lld\n",BinSearch(Min,L));
    }
    return 0;
}

时间: 2024-10-15 17:24:26

poj3258——二分优化的相关文章

最长上升子序列的二分优化

http://blog.csdn.net/wall_f/article/details/8295812 作者写的太好了,转载一下~ 我简单总结一下,我的理解. 最长上升子序列的转移方程:b[k]=max(max(b[j]|a[j]<a[k],j<k)+1,1); 其优化主要在求解当前最长长度是要查找前面的b数组中是否有最大的值,且当前期a[j]<a[k],因此就是要找小于当前值的最大值. 所以我们一般需要从1~k-1扫描一遍找到最大值,复杂度为o(n^2),耗时太长. 因此我们可以直接记

HDU 1025:Constructing Roads In JGShining&#39;s Kingdom(LIS+二分优化)

http://acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in two parallel lines.Half of these cities are r

硬币问题 (dp,多重背包的二分优化)

题目描述 给你n种硬币,知道每种的面值Ai和每种的数量Ci.问能凑出多少种不大于m的面值. 输入 有多组数据,每一组第一行有两个整数 n(1≤n≤100)和m(m≤100000),第二行有2n个整数,即面值A1,A2,A3,…,An和数量C1,C2,C3,…,Cn (1≤Ai≤100000,1≤Ci≤1000).所有数据结束以2个0表示. 输出 每组数据输出一行答案. 样例输入 3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0 样例输出 8 4 背包问题的复杂度是n*m,这题如果

POJ 3903:Stock Exchange(裸LIS + 二分优化)

http://poj.org/problem?id=3903 Stock Exchange Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5983   Accepted: 2096 Description The world financial crisis is quite a subject. Some people are more relaxed while others are quite anxious. J

poj3273——经典的二分优化

poj3273——经典的二分优化 Monthly Expense Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16522   Accepted: 6570 Description Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already

HDU 1025 LIS二分优化

题目链接: acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 28755    Accepted Submission(s): 8149 Problem Description

51nod 1267二分+优化试验场

最初,最开始的时候,万能的学姐曾经警告过我们,千万别用什么老狮子MAP,手撸map或者字典树...当时不甚理解...今天...这题直接卡掉了我的MAP,但是使用朴素方法进行二分...不加优化,,都不需要这个架势...直接相差了将近十倍,在我开了优化之后快了20倍左右.... 上代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const long long MAXN=1233; 5 6 7 class node 8 { 9 pub

HDU 5652 India and China Origins 二分优化+BFS剪枝

题目大意:给你一个地图0代表可以通过1代表不可以通过.只要能从第一行走到最后一行,那么中国与印度是可以联通的.现在给你q个点,每年风沙会按顺序侵蚀这个点,使改点不可通过.问几年后中国与印度不连通.若一直联通输出-1. 题目思路:看数据这道题就是卡时间的,我们的基本思路是每当风沙侵蚀一个点,我们就进行一次广搜,看看图上下是否联通,我们应尽可能的去优化这个过程. 所以我们可以在遍历年的时候用二分查找: 若当年图可以上下联通,则继续向右查找 若当年图上下无法联通,则向左查找 剪枝: 为了省时间我们应该

[POJ1631]Bridging signals (DP,二分优化)

题目链接:http://poj.org/problem?id=1631 就是求一个LIS,但是范围太大(n≤40000),无法用常规O(n²)的朴素DP算法,这时需要优化. 新加一个数组s[]来维护长度当LIS的长度为len时候需要的数组a中的最小数字的值,可以证明这个数组是严格单调递增的,因此可以二分确定每次枚举到a[i]的时候,a[i]在这个数组中所处的位置(下标),也就是a[i]数字时此时之前算过的LIS的长度.之后更新s数组和ans即可.对于最长下降自序列此方法同样适用,但是需要注意那时