小a与星际探索(dp)

链接: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
  • 输出描述:
    一个整数表示到达n号星球时最大的耐久度
    若不能到达n号星球或到达时的最大耐久度为0则输出−1
  • 输入
    3
    457 456 23
  • 输出
    478
  • 说明
    小a有两种方法到达3号星球
    第一种:1→2→3,最终耐久度为457⊕456⊕23=22
    第二种:1→3,最终耐久度为457⊕23=478
  • 输入
    4
    2 4 4 2
  • 输出
    -1
  • 输入
    5
    234 233 123 2333 23
  • 输出
    253
  • 备注:1⩽n,∀pi⩽3000

  emmmm...还是有点懵懵的,还有一些地方无法解释,直接贴代码吧.

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#define pi 3.1415926
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;

//typedef pair<int,int> Node;
typedef long long  LL;
const int Max_n=1<<14;//这里一定要写成左移的形式(不知道为什么) 
int a[Max_n],b[Max_n];
bool  dp[Max_n];

int main(){ 
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	memset(dp,false,sizeof(dp));
	if(a[1]<=a[n]){//飞船无法从1到达n 
		printf("-1\n");
		return 0;
	}
	int num=1;
	dp[a[1]^a[n]]=true;//这个耐久度的值(a[1]^a[n])可以达到
	for(int i=2;i<n;i++){
		if(a[i]<a[1]&&a[i]>a[n])
			b[num++]=a[i];//由于不进行排序所以这里要筛选出1~n之间可以经过的点 
	} 
	for(int i=1;i<num;i++){
		for(int j=Max_n-1;j>=0;j--){ 
			dp[j]|=dp[j^b[i]];//这里注意或运算规则
			//如果之前能够到达j^b[i],那么他一定可以到达j(之前能够到达j^b[i],当前可以选择b[i],j^b[i]^b[i]=j) 
		}
	} 
	int ans=1;
	for(int i=Max_n-1;i>=0;i--){
		if(dp[i]){
			ans=i;
			break;
		}
	} 
	printf("%d\n",ans?ans:-1);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值