小a与星际探索 线性基算法

本文介绍了一个星际探索游戏的问题,通过线性基算法解决飞船从1号星球前往n号星球时如何使耐久度最大化。文章详细解释了算法原理,包括线性代数的化阶梯型矩阵和贪心思想的应用,最后提供了实现代码。

链接: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值