刷题Day12又一个基础递归搜索

前言

 本题属于比较基础的递归搜索策略,因为此类题目刷的比较多了,所以不做太多讲解
P2392 kkksc03考前临时抱佛脚
在这里插入图片描述
在这里插入图片描述
解题思路:
 本题的题目有点长但是题意还是比较容易理解的。可以简单理解为对这四列中的每一列,分为两个子列并计算子列的和,最大的子列和代表这列贡献的时间然后算四列时间的加和。
 依旧是比较基础的递归搜索策略,因为无序回溯,所以每次向下递归的时间只要用两个变量total_right和total_left即可记录下当前左右子列的和,并且向下递归计算将当前数归入左子列和右子列的情况,当递归搜索中left大于right表明搜索完,这时候通过max(total_right,total_left)就可以比较出当前的时间值,然后与全局的记录最小时间值的变量比较大小,更新,即可。最终搜索完可以覆盖所以情况并且因为无需回溯所以最终的min即为当前列的时间值;依次对其余列执行相同操作即可。
 给出我的AC代码:

#include <stdio.h>
#include <stdlib.h>
#define inf 140000000
int min1=inf,min2=inf,min3=inf,min4=inf;
int max(int a,int b){
	if(a>=b)
	  return a;
	else
	  return b;
}

void search1(int left,int right,int a[],int total_left,int total_right){
	if(left>right){
		if(min1>max(total_left,total_right))
		  min1=max(total_left,total_right);
		return;
	}

	search1(left+1,right,a,total_left+a[left],total_right);
	search1(left+1,right,a,total_left,total_right+a[left]);
}
void search2(int left,int right,int a[],int total_left,int total_right){
	if(left>right){
		if(min2>max(total_left,total_right))
		  min2=max(total_left,total_right);
		return;
	}

	search2(left+1,right,a,total_left+a[left],total_right);
	search2(left+1,right,a,total_left,total_right+a[left]);
}
void search3(int left,int right,int a[],int total_left,int total_right){
	if(left>right){
		if(min3>max(total_left,total_right))
		  min3=max(total_left,total_right);
		return;
	}

	search3(left+1,right,a,total_left+a[left],total_right);
	search3(left+1,right,a,total_left,total_right+a[left]);
}
void search4(int left,int right,int a[],int total_left,int total_right){
	if(left>right){
		if(min4>max(total_left,total_right))
		  min4=max(total_left,total_right);
		return;
	}

	search4(left+1,right,a,total_left+a[left],total_right);
	search4(left+1,right,a,total_left,total_right+a[left]);
}
int main(int argc, char *argv[]) {
	int s[5],i,j,min[5];
	for(i=1;i<=4;i++){
		scanf("%d",&s[i]);
	}
	int a[s[1]],b[s[2]],c[s[3]],d[s[4]];
	for(i=0;i<s[1];i++)
	  scanf("%d",&a[i]);
	for(i=0;i<s[2];i++)
	  scanf("%d",&b[i]);
	for(i=0;i<s[3];i++)
	  scanf("%d",&c[i]);
	for(i=0;i<s[4];i++)
	  scanf("%d",&d[i]);
	search1(0,s[1]-1,a,0,0);
	search2(0,s[2]-1,b,0,0);
	search3(0,s[3]-1,c,0,0);
	search4(0,s[4]-1,d,0,0);
	printf("%d",min1+min2+min3+min4);
	
	
	
	
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值