题意: 现有初始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;
}

京公网安备 11010502036488号