【挑战程序设计】利用二分搜索计算最优解问题 JAVA实现

**

【挑战程序设计】利用二分搜索计算最优解问题 JAVA实现

**

题目要求

传送带依次送来了重量分别为wi(i = 0, 1,…, n - 1)的n个货物。现在要将这些货物装到k辆卡车上。每辆卡车可装载的货物数大于等于0,但货物重量总和不得超过卡车的最大运载量P。所有卡车的最大运载量P一致。请编写一个程序,输入__n,k,w[i]__求出装载全部货物所需的最大运载量P的最小值。

输入:

第一行输入整数n和k,用空格隔开。接下来n行输入n个整数wi,每个数占一行。
输出: 输出P的最小值,占1行。

限制:

1≤n≤100000
1≤k≤100000
1≤wi≤10000

输入示例

输入示例

输出示例

在这里插入图片描述
这里大概的思路是有一个checkP方法,返回值为j(货车最大运载量为P时装的货物数),假设将P放在一个很大的集合里,现在不知道P的值,利用二分法得到mid,利用check(mid)方法不断缩小P的范围,判断条件是while(right-left)>1,直到找到最小的P,也就是P,返回right(right就是满足条件的最小P),因为最后的结果一定是v(k辆最大运载量为P的货车能装的货物数)>=n,若小于n,肯定不满足题目(货车装不下)。则一定返回的是right所记录的mid值。

具体代码

package optimalSolution;

public class Method {	
	
	//k辆最大运载量为P的货车能装多少个货物
	public int checkP(int k,int P,int w[],int n) {
		int sum;
		int j = 0;
		for (int i = 0; i < k; i++) {
			sum = 0;
			while(sum+w[j]<=P) {     //当sum加下一个货物重量时,若超过P,则返回j,j为货物个数,从0开始
				sum+=w[j];
				j++;
				if(j==n) return j;   //若P过大的话,可能发生这种情况,一辆货车可以装所有的货物,返回j=n
			}
		}
		return j;    //j从0开始,因此不需要j-1
	}
	
	//利用二分搜索查找P的最小值
	public int findP(int k,int w[],int n) {
		int left = 0;    //P集合的最左侧
		int right = 10000*10000;      //P集合的最右侧,最大货物数*最大货车数,注意看题目的限制
		int mid = 0;
		int v = 0;
		while(right-left>1) {
			mid = (left+right)/2;
			v = checkP(k,mid,w,n);    //v记录了一个货车可以装多少个货物
			if(v>=n) right = mid;
			else left =mid; 
		}
		return right;
	}
}

package optimalSolution;

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// 二分搜索计算最优解
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入:");
		int n = scan.nextInt();   //n个货物
		int k = scan.nextInt();   //k个货车
		int[] w = new int[n];     //wi不同重量的货物数组
		Method m = new Method();
		for (int i = 0; i < n; i++) {
			w[i] = scan.nextInt();
		}
		System.out.println(m.findP(k, w, n));
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值