题意: 现有初始x=0,以及两个长度为n的a,b数组,我们要进行n次操作,每次操作可以选择将x更新为max(x-a[i],0)或更新为x^b[i]。使得n次操作后最大化x。

知识点: 动态规划

思路: 从题意可以看出,他最终操作不会大于2^i(i是b数组中最大数的二进数位数),因为异或不会产生一个新的高位出来,减法更是只能减少。

所以我们可以考虑用值域动态规划,因为你直接从结果看,他第一轮产生2个结果,第二轮产生4个结果,第N轮产生个结果,所以他最大会产生2的几千次方个结果,但是其中大部分都是重复的,因为他不会超过2048。

因此用值域来搜索,每一次将上一轮产出的所有可能数按照max(x-a[i],0)和x^b[i]这两种可能更新,但是因为我们按照值域查找所以每一轮最多查找2048次,最多2048轮,完全不会超时。

当然你要是闲的蛋疼觉得这个策略前期的性能不尽人意,你也可以前期使用第一轮产生2个结果,第二轮产生4个结果的策略,直到他的性能不如值域搜索在更改搜索策略,只是性能的优化微乎其微,不建议这么搞。

参考代码:

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define PLL pair<ll,ll>
#define PII pair<int,int>
#define endl '\n'
using namespace std;
int main()
{
	cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
	int n;
	cin >> n;
	vector<int> a(n),b(n);
	vector<bool> dp(2048,0);
	dp[0]=1;
	for(int i=0;i<n;i++)
		cin >> a[i];
	for(int i=0;i<n;i++)
		cin >> b[i];
	for(int i=0;i<n;i++){
		vector<bool> ndp(2048,0);
		for(int j=0;j<2048;j++){
			if(!dp[j])
				continue;
			int x=max(j-a[i],0),y=j^b[i];
			ndp[x]=ndp[y]=1;
		}
		dp=ndp;
	}
	for(int i=2047;i>=0;i--)
		if(dp[i]){
			cout << i;
			return 0;
		}
	cout << 0;
	return 0;
}