切割木头算法

问题如图: 注 :木头不一定都要用,用也不一定都要用完 问题可以转化成在1和给的所有原木中最长的长度中间找一个合适的长度,使得把每段原木按此分段后得到的小段木头数目至少为k:在1—max之间用折半查找,找到最大的长度 //def woodCut(self, L, k){ // if

问题如图:
这里写图片描述

:木头不一定都要用,用也不一定都要用完

  1. 问题可以转化成在1和给的所有原木中最长的长度中间找一个合适的长度,使得把每段原木按此分段后得到的小段木头数目至少为k:在1—max之间用折半查找,找到最大的长度

//def woodCut(self, L, k){
//  if sum(L) < k :
//  return 0
//
//      start, end = 1, max(L)
//      while start + 1 < end :
//          mid = start + (end - start) / 2
//          pieces = sum([l / mid for l in L])
//          if pieces >= k :
//              start = mid
//          else :
//          end = mid
//
//          if sum([l / end for l in L]) > k:
//  return end
//      return start
//}
#include <stdio.h>
#include <numeric>

using namespace std;

int k(0);
int array[10000];
int len(0), max_wood(0);

int WoodCut()//二分查找上界
{
    int sum = accumulate(array, array+len,0);
    if (sum < k)
        return 0;

    int left(1), right(max_wood);
    int mid;
    while (left+1<right)
    {
        mid = left + (right - left) / 2;
        int k_tmp(0);

        for (auto i = 0; i <= len ;i++)
        {
            k_tmp += array[i] / mid;
        }

        if (k_tmp>=k)
        {
            left = mid;
        }
        else
        {
            right = mid;
        }
    }
    int right_k(0);
    for (auto i = 0; i <= len; i++)
    {
        right_k += array[i] / right;
    }
    if (right_k>=k)
    {
        return right;
    }
    else
    {
        return left;
    }

    return 0;
}

int main()
{
    char c;
    scanf("%d", &k);
    while (1)
    {
        scanf("%d", &array[len]);
        if (array[len]>max_wood  )
        {
            max_wood = array[len];
        }
        c = getchar();
        if (c=='\n')
        {
            break;
        }
        ++len;
    }
    printf("%d",WoodCut());

    return 1;
}
知秋君
上一篇 2024-08-25 17:48
下一篇 2024-08-25 17:12

相关推荐