Lizard Era: Beginning

本文介绍了一种通过折半搜索优化暴力DFS算法,解决任务分配问题,通过map存储中间步骤,以寻找最优解决方案。
摘要由CSDN通过智能技术生成

题目

在这里插入图片描述

思路

暴力dfs会TLE,考虑折半搜索
将每次任务分为左边获得的和右边获得的
l 1 + r 1 = l 2 + r 2 = l 3 + r + 3 l_1+r_1=l_2+r_2=l_3+r+3 l1+r1=l2+r2=l3+r+3
为了让左边搜索时只依赖l,右边只依赖r,所以移项变为
r 1 − r 2 = l 2 − l 1 r_1-r_2=l_2-l_1 r1r2=l2l1, r 1 − r 3 = l 3 − l 1 r_1-r_3=l_3-l_1 r1r3=l3l1
先搜左边,将所得的 l 2 − l 1 l_2-l_1 l2l1 l 3 − l 1 l_3-l_1 l3l1存入pair中作为key在map中指向结构体tmp
tmp存得到这个pair的步骤(xu数组)和 l 1 l_1 l1
为了让 l 1 l_1 l1尽可能大,我们在更新时只存 l 1 l_1 l1较大的tmp

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=30;
int n;
int a[maxn],b[maxn],c[maxn];
int opt[maxn],now[maxn];
char ANS[][3]={"xx","LM","MW","LW"};
struct node{
	int xu[maxn];
	int l1;
	node() { l1=0;memset(xu,0,sizeof(xu)); }
};
map<pair<int,int>,node> mp;
int ans=-1e9;
void cpy(int *a,int *b,int st,int en) { for(int i=st;i<=en;i++) a[i]=b[i]; }
void dfs1(int i,int l1,int l2,int l3){
	if(i==n/2+1){
		int a1=l2-l1,a2=l3-l1;
		pair<int,int> t=make_pair(a1,a2);
		if(mp.count(t)&&mp[t].l1>l1) return;
		node tmp;tmp.l1=l1;
		cpy(tmp.xu,now,1,n/2);//前半部分的步骤
		mp[t]=tmp;
		return;
	}
	//模拟三种情况
	now[i]=1,dfs1(i+1,l1+a[i],l2+b[i],l3);
	now[i]=2,dfs1(i+1,l1,l2+b[i],l3+c[i]);
	now[i]=3,dfs1(i+1,l1+a[i],l2,l3+c[i]);
}
void dfs2(int i,int r1,int r2,int r3){
	if(i==n+1){
		int b1=r1-r2,b2=r1-r3;
		pair<int,int> t=make_pair(b1,b2);
		if(!mp.count(t)) return;
		if(mp[t].l1+r1>ans) cpy(opt,mp[t].xu,1,n/2),cpy(opt,now,n/2+1,n),ans=mp[t].l1+r1;
		return;
	}
	now[i]=1,dfs2(i+1,r1+a[i],r2+b[i],r3);
	now[i]=2,dfs2(i+1,r1,r2+b[i],r3+c[i]);
	now[i]=3,dfs2(i+1,r1+a[i],r2,r3+c[i]);
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i]>>c[i];
	dfs1(1,0,0,0),dfs2(n/2+1,0,0,0);
	if(ans==-1e9) { cout<<"Impossible";return 0; }
	for(int i=1;i<=n;i++) cout<<ANS[opt[i]]<<endl;
	return 0;
}

end

完结撒花

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值