链接:https://ac.nowcoder.com/acm/contest/317/C
来源:牛客网
题目描述
小a正在玩一款星际探索游戏,小a需要驾驶着飞船从1号星球出发前往n号星球。其中每个星球有一个能量指数p。星球i能到达星球j当且仅当pi>pj。
同时小a的飞船还有一个耐久度t,初始时为1号点的能量指数,若小a前往星球j,那么飞船的耐久度会变为t⊕pj(即t异或pj,关于其定义请自行百度)
小a想知道到达n号星球时耐久度最大为多少
注意:对于每个位置来说,从它出发可以到达的位置仅与两者的p有关,与下标无关
输入描述:
第一行一个整数n,表示星球数
接下来一行有n个整数,第i个整数表示pi
1⩽n,∀pi⩽3000
输出描述:
一个整数表示到达n号星球时最大的耐久度
若不能到达n号星球或到达时的最大耐久度为0则输出−1
样例
输入
5
234 233 123 2333 23
输出
253
题解
第一次接触线性基这个算法,用到线性代数的化阶梯型矩阵,化成阶梯型矩阵,用贪心的思想,尽量让高位为1.复杂度15O(n),
比背包dp快
代码
#include<algorithm>
#include <iostream>
#include<vector>
#include<cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=3005;
int n;
int a[maxn];
int main(){
cin>>n;
for(int i=0;i<n;i++){
scanf("%d",a+i);
}
if(n==1) cout<<(a[0]?a[0]:-1)<<endl;// 边界条件,只有一个数,如果值为0输出-1
else if(a[0]<=a[n-1]) cout<<-1<<endl;
else{
vector<int> v;
for(int i=1;i<n-1;i++){
if(a[i]<a[0]&&a[i]>a[n-1]){
v.push_back(a[i]);
}
}
if(v.size()){
for(int i=14,k=0;i>=0;i--){
for(int j=k;j<v.size();j++){
if(v[j]>>i&1){
swap(v[j],v[k]);
break;
}
}
if(v[k]>>i&1){
for(int j=k+1;j<v.size();j++){
if(v[j]>>i&1){
v[j]^=v[k];
}
}
k++;
}
}
}
int ans=a[0]^a[n-1];
if(v.size()){
for(int i=14,k=0;i>=0;i--){
if(v[k]>>i&1){
if(!(ans>>i&1)){
ans^=v[k];
}
k++;
}
}
}
cout<<ans<<endl;
}
return 0;
}