poj3273

题目还是有思维量的。大致题意为给定n个整数,要求分成m组,求出各种组合方式中每组最大的和的最小值。那么这题,最开始想到的依然是暴力。枚举所有可能的组合方式,加上剪枝,TLE。于是想用二分查找法求解单调函数。思路如下:

选定一个数x,将n个数按照每组最大x且组合个数最小的方式组合(贪心法求解对于每个x的最小组合个数)

1)如果最小组合个数大于m,则说明x的值一定小于要求的值,不满足要求

2)如果最小组合个数小于或等于m,则说明满足要求,可以组成m组,但是必须为这些数中的最小值。

而x的取值范围为min(record[i])——sum(record[i])(包括min,sum)。同时,用这些数按照上述方式组合,其最小组合个数单调递减(不严格单调递减),我们只需要用二分查找寻找出满足最小组合个数<=m的第一个数就可以了。下面是代码:

先给出dfs+剪枝代码(TLE):

#include<stdio.h>
#include<stdlib.h>
#define Max 100010
#define Maxx(a,b) (a)>(b)?(a):(b)
#define Inf 1000000010
int record[Max];
int n,m;
int Sum;
void dfs(int index,int num,int inf){
	//if(inf>=Sum)
		//return ;
	if(index==m){
		int temp=0;
		for(int i=num;i<=n;i++)
			temp+=record[i];
		temp=Maxx(temp,inf);
		if(temp<Sum)
			Sum=temp;
		return ;
	}
	int temp=0;
	for(int i=num;i<=n-(m-index);i++){
		temp+=record[i];
		int  t=Maxx(inf,temp);
		if(t>=Sum)
			return ;
		dfs(index+1,i+1,t);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&record[i]);
	Sum=Inf;
	dfs(1,1,0);
	printf("%d\n",Sum);
	return 0;
}

下面是二分查找求单调函数代码: 524K+63MS

#include <stdio.h>
#include <stdlib.h>
#define Max 100010 //最大个数
int record[Max];
int n,m;
int main(){
	while(scanf("%d%d",&n,&m)!=EOF){
	int INf=0,Sum=0;
	for(int i=1;i<=n;i++){ 
		scanf("%d",&record[i]);
		if(record[i]>INf)
			INf=record[i]; //求最大值
		Sum+=record[i]; // 最和
	}
	int left=INf,right=Sum,mid; //在INf和Sum之间用二分查找法求解单调函数
	while(left<=right){
		mid=(left+right)>>1; 
		int temp=0,num=1;
		for(int i=1;i<=n;i++){ //贪心法求以mid为最大上限按上述组合方式组合的最小组合个数
		    temp+=record[i];
			if(temp>mid){
				num++;
				if(num>m)
					break;
				temp=record[i];
			}
		}
		if(num>m) //若个数大于m,则说明mid不够大
			left=mid+1;
		else if(num<=m) // 求解满足要求的最小值
			right=mid-1;
	}
	printf("%d\n",mid); // 输出最小值
	}
	return 0;
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值