题目描述
皮带运输机有按照顺序(i=0,1,…n−1)的n包裹重量为wi。您应该将所有包裹装载到具有共同最大负载P的k卡车上。除非顺序中包裹的总重量不超过最大负载P,否则每辆卡车可以从带式输送机装载连续包裹(大于或等于零)。
编写一个程序,读取n,k和wi,并输出最大负载P的最小值,以便从带式输送机上装载所有包裹。
输入:在第一行中,两个整数n和k由一个空格字符分隔。在下面的n行中,分别给出wi。
输出:打印p的最小值
测试输入:
5 3
8
1
7
3
9
测试输出:
10
显然装载方案是我们无法控制的,能做的只有找出一个最小的解。
数轴是天然的有序序列,遍历太慢,利用二分在数轴上查找这个解,不需要很精细的代码就可以AC:
#include<iostream>
using namespace std;
bool judge(int n,int k,int w[],int p)
{//判断p是不是一个可行解
int car_sum = k-1;
int car_afford = p;
for (int i = 0; i < n; i++)
{
car_afford -= w[i];
if (car_afford < 0)
{
car_sum--;
car_afford = p;
i--;
if (car_sum < 0)
return false;
}
}
return true;
}
int main()
{
int n;
int k;
int w[max];
int sum=0;
cin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> w[i];
sum+=w[i];
}
int Max = sum;
int Min = sum/k;
int mid = (Max + Min) / 2;
while (Max > Min)
{
mid = (Max + Min) / 2;
if (judge(n, k, w, mid))
Max = mid - 1;
else
Min = mid + 1;
}//二分查找可行解最小值,注意最后输出未必可行
//如果懒得判断可行性和二分正确性,可以直接向两边遍历,不会很耗时
//如有大佬能够准确判断请留言指教
if(judge(n, k, w, mid))
while (1)
{
if (judge(n, k, w, mid))
mid--;
else
{
cout << mid + 1;
break;
}
}
else
while (1)
{
if (!judge(n, k, w, mid))
mid++;
else
{
cout << mid;
break;
}
}
}