二分贪心练习题-E5

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000).  His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input

* Line 1: Two space-separated integers: N and C  * Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output

* Line 1: One integer: the largest minimum distance

Sample Input

5 3
1
2
8
4
9

Sample Output

3

题意:
    先输入两数,表示牛舍数与要放下多少头牛,后面给出牛舍的位置(牛舍在一条直线),求出放完牛后有牛的牛舍之间最小距离中的最大值
分析:
    一定数量的牛舍,一个位置只能放一头牛,那么要放入的牛数量越多,牛舍之间距离相对越小,所以可以用二分法做,我用judge函数判断x距离下能否放下这C头牛,二分循环找出可以放下这C头牛的最大的两舍之间的最小距离。
吐槽:
    本题我提交了好多次,最后发下超时的原因竟然是cin的输入速度太慢,换成scanf就AC了
#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<string.h>
using namespace std;
int m,n,a[100002];
bool judge(int x)
{
    int g=a[0],f=1;
    for(int i=0;i<n;i++)
    {
        if(a[i]-g>=x)
        {
            f=f+1;//符合距离要求,放下一头牛
            g=a[i];
            if(f>=m){return true;}访完了,可以
        }
    }
    return false;
}
int main()
{
    int k,max=-1,ans=0,beg,end,mid;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);  
        if(a[i]>max){max=a[i];}
    }
    sort(a,a+n);
    end=max-a[0];beg=1;
    ans=1;
    while(beg<=end)//逐步找出符合要求的最小距离,在诸多都可以放下C头牛的最小距离中找出最大值
    {
        mid=(end+beg)/2;
        if(judge(mid))
        {
            ans=mid;
            beg=mid+1;
        }
        else
        {
            end=mid-1;
        }
    }
    cout<<ans;
}
<think>好的,我现在需要回答用户关于贪心算法在采花生问题中的应用的问题。首先,我需要回忆一下采花生问题的具体内容。采花生问题通常是指在一个网格中,每个格子有一定数量的花生,一个人从左上角出发,每次只能向右或向下移动,最终到达右下角,要求收集到最多的花生。这应该是一个动态规划问题,但用户提到的是贪心算法,可能需要先理清楚两者的区别。 用户可能混淆了贪心算法和动态规划的应用场景。贪心算法通常每一步都选择当前最优,但可能无法得到全局最优解。而像采花生这样的问题,由于路径的选择会影响后续的结果,需要全局考虑,因此更适合用动态规划来解决。例如,每个位置的最大花生数只能由左边或上边的位置决定,因此需要递推计算每个位置的值。 接下来,我需要确认用户提供的引用内容是否有相关的信息。查看用户给出的引用,引用[1]提到了动态规划的相关内容,包括摘花生问题的题解,这可能与用户的问题相关。引用[4]中的示例测试样例可能涉及到类似的问题,但可能不是直接相关。 用户要求示例代码和解题思路,因此我需要先解释为什么贪心算法在这里不适用,然后转而介绍动态规划的解法。同时,需要提供代码示例,可能参考引用中的信息,比如引用[1]中的摘花生题目代码题解部分。 需要注意用户的引用中的摘花生问题可能正是用户所说的采花生问题,所以需要结合引用[1]的内容来回答。根据动态规划的思路,每个位置的最大花生数等于其左边或上边最大值加上当前格子的花生数。代码实现通常使用二维数组来存储中间状态,逐步填充数组,最终右下角的值即为答案。 可能用户误以为这个问题可以用贪心算法解决,但实际上正确的解法是动态规划。因此,在回答时需要指出这一点,并解释贪心算法在此场景中的局限性,例如贪心每次选择当前最大花生路径可能会导致错过全局更优的路径。 最后,生成相关问题时要围绕贪心算法和动态规划的区别,以及采花生问题的其他解法或变体来提问。</think>### 贪心算法在采花生问题中的应用分析 采花生问题的典型场景是:给定一个$m \times n$的网格,每个格子有若干花生,从左上角出发,只能向右或向下移动,最终到达右下角,求能收集的最大花生数。**此问题需用动态规划而非贪心算法解决**,原因如下: 1. **贪心算法的局限性** 贪心算法每一步选择当前最优(如向右或向下中花生更多的方向),但局部最优无法保证全局最优。例如: $$ \begin{matrix} 100 & 1 & 1 \\ 1 & 1 & 100 \end{matrix} $$ 若第一步贪心选择向右(100→1),则无法到达右下角的100;而动态规划会提前计算所有路径。 2. **动态规划的正确性** 定义状态$dp[i][j]$表示到达$(i,j)$时的最大花生数,状态转移方程为: $$ dp[i][j] = \max(dp[i-1][j], dp[i][j-1]) + grid[i][j] $$ 通过递推计算所有位置,最终$dp[m-1][n-1]$即为答案。 --- ### 动态规划实现代码(Python示例) ```python def max_peanuts(grid): m, n = len(grid), len(grid[0]) dp = [[0] * n for _ in range(m)] dp[0][0] = grid[0][0] # 初始化第一行和第一列 for i in range(1, m): dp[i][0] = dp[i-1][0] + grid[i][0] for j in range(1, n): dp[0][j] = dp[0][j-1] + grid[0][j] # 填充其余位置 for i in range(1, m): for j in range(1, n): dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + grid[i][j] return dp[-1][-1] ``` --- ### 关键点说明 - **初始化处理**:第一行和第一列只能通过单一方向累加得到[^1]。 - **时间复杂度**:$O(mn)$,优于暴力枚举所有路径的指数复杂度。 - **空间优化**:可用滚动数组将空间复杂度优化至$O(n)$。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值