Array:深搜加剪枝

本文介绍了一种结合深度搜索和剪枝策略的算法,用于在给定约束条件下求解最优化问题。通过异或运算和特定条件剪枝,算法能有效地减少搜索空间,提高效率。在每次操作后,算法会更新当前的最大值,并在奇数层和偶数层结束时分别更新最大值。最后,通过实例展示了算法的运行过程和结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深搜加剪枝,剪枝根据两次异或以后值为本身来写

#include<iostream>
#include<stdio.h>
using namespace std;
#define sc scanf
#define co cout
#define e endl
int maxx,n,m,t,floor;
int b[30],c[30],d[30];
void update(int a[30]){
	int tmp = 0;
	for(int i=1;i<=n;i++){
		tmp +=  a[i] * c[i];
	}
	//co<<tmp<<e;
	if(tmp>maxx) maxx = tmp;
}
void def(int count,int a[30],int aa[30],int flag){//flag代表进入当前节点前进行的操作 ,count第几次操作,a代表当前要传入的a数组的值,aa代表a上一步的操作的a的值
													// 实际上aa数组只有操作1会用到,操作2的aa可以随便填 当传入的flag==1,下一次就没必要使用def(count+1,a,aa,1) 而是将这步操作省略,就是直接剪掉 
													//  操作0就是从根节点进入的时候还有连续两次操作1清空操作的时候使用 
													//在奇数层结束,更新奇数层的所有最大值,在偶数层结束,更新所有偶数层的最大值 
													//更新不能在开头更新 
	if(count==m){//叶节点必须更新,根节点进入且偶数次操作更新 
		update(a);
		return ;
	} 
	if(count%2==floor||(count==0&&floor==0)){
		//co<<"test"<<e;
		update(a);
	} 
	if(flag==0){//更新操作1和操作2需要的a数组值
		int a1[30],a2[30]; 
		for(int i=1;i<=n;i++){//不论是根节点进入,还是连续两次1操作进入,都套用aa数组,根节点进入aa数组就是一开始的数组a 
			a1[i] = aa[i] ^ b[i];
			a2[i] = aa[d[i]] + t;
		}
		def(count+1,a1,aa,1);
		def(count+1,a2,aa,2);
	}else if(flag==1){//之前进行1操作 
		int a2[30];
		for(int i=1;i<=n;i++){
			a2[i] = a[d[i]] + t;
		}
		//def(count+1,a1,aa,1);1操作替换掉
		//def(count+1,a,aa,0); 可以剪枝 
		def(count+1,a2,aa,2);
	}else if(flag==2){//之前进行2操作,其他操作按计划进行 
		int a1[30],a2[30];
		for(int i=1;i<=n;i++){
			a1[i] = a[i] ^ b[i];
			a2[i] = a[d[i]] + t;
		}
		def(count+1,a1,aa,1);
		def(count+1,a2,aa,2);
	}
	return ;
}
int main(){
	int a[30];
	while(sc("%d %d %d",&n,&m,&t)!=EOF){//每次输入,重置奇数偶数层m判断,重置最大值 
		maxx = -100000000;//必须为该值,极端情况一个数操作一次,a是10000,c是-10000
		floor = m%2;
		for(int j=1;j<=n;j++){
			sc("%d",&a[j]);
		}
		for(int j=1;j<=n;j++){
			sc("%d",&b[j]);
		}
		for(int j=1;j<=n;j++){
			sc("%d",&c[j]);
		}
		for(int j=1;j<=n;j++){
			sc("%d",&d[j]);
		}
		def(0,a,a,0);
		co<<maxx<<e;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值