本文共 3004 字,大约阅读时间需要 10 分钟。
目录
这真的是我最近一段时间做的最艰辛的一个题解了,想哭。
法一:线性基
在b站上看赛后题解视频学的,链接失效了...
线性基算法用到线性代数的化阶梯型矩阵,化成上三角矩阵,最后用贪心的思想,从高位到低位尽量让0->1,时间复杂度O(n)。
法二:搜索bfs
异或到n作为更新答案的条件,遍历从p[1]到p[n]的符合条件的所有星球的选择与否情况,时间复杂度O(n*n)。
法三:背包dp
看做是容量为M的背包装cnt个满足条件的物体,装物体的过程中装载量不是求和而是求异或,问最大装载量这样。
2的十次方是1024,12次就超过3000了,我们把M设成12位都是1即2^12-1的大小,遍历寻找最大的状态即可,时间复杂度O(n*n)。
(这里感谢哲神的大力支持yyy)
#includeusing namespace std;typedef long long ll;const int maxn=3005;int main(){ int n; cin>>n; int a[maxn]; for(int i=0;i
#includeusing namespace std;int n,ans;bool vis[5005];int p[3005];void bfs(){ queue q; q.push(p[1]); memset(vis, false, sizeof(vis)); vis[p[1]] = true; while(!q.empty()) { int now=q.front(); q.pop(); for(int i=2;i<=n;i++) { if(now>p[i]) { int next=now^p[i]; if(i==n) ans=max(ans,next); if(!vis[next]&&i 0?ans:-1); return 0;}
#includeusing namespace std;const int M=1<<12;int dp[M],p[3005],a[3005];int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&p[i]); if(n==1) printf("%d\n",p[1]?p[1]:-1); else if(p[1]<=p[n]) puts("-1"); else { int cnt=0,ans; for(int i=2;i<=n-1;i++) if(p[1]>p[i]&&p[i]>p[n]) a[++cnt]=p[i]; dp[p[1]^p[n]]=1; for(int i=1;i<=cnt;i++) for(int j=M-1;j>=0;j--) dp[j^a[i]]|=dp[j]; for(int i=M-1;i>=0;i--) if(dp[i]) { ans=i; break; } printf("%d\n",ans); } return 0;}
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld小a正在玩一款星际探索游戏,小a需要驾驶着飞船从11号星球出发前往nn号星球。其中每个星球有一个能量指数pp。星球ii能到达星球jj当且仅当pi>pjpi>pj。
同时小a的飞船还有一个耐久度tt,初始时为11号点的能量指数,若小a前往星球jj,那么飞船的耐久度会变为t⊕pjt⊕pj(即tt异或pjpj,关于其定义请自行百度) 小a想知道到达nn号星球时耐久度最大为多少注意:对于每个位置来说,从它出发可以到达的位置仅与两者的pp有关,与下标无关
第一行一个整数nn,表示星球数接下来一行有nn个整数,第ii个整数表示pipi
一个整数表示到达nn号星球时最大的耐久度若不能到达nn号星球或到达时的最大耐久度为00则输出−1−1
示例1
复制
3457 456 23
复制
478
小a有两种方法到达33号星球第一种:1→2→31→2→3,最终耐久度为457⊕456⊕23=22457⊕456⊕23=22第二种:1→31→3,最终耐久度为457⊕23=478457⊕23=478
示例2
复制
42 4 4 2
复制
-1
示例3
复制
5234 233 123 2333 23
复制
253
1⩽n,∀pi⩽3000
转载地址:http://mfben.baihongyu.com/