小a与星际探索
题意就是让你找一条1到n的路径使得路径上点的异或和最大。
这里定义了f[i]表示为1到达n,耐久度为i是否可行,先判断p[1]是否是>p[n]的,否则的话无解,是的话先给f[p[1]^p[n]]=1,表示这个状态是可行的,然后利用p值在p[1],p[n]之间的点作为中转点,拓展可行的状态,(这里利用了异或运算满足交换律和异或的自反性)
#include<bits/stdc++.h>
using namespace std;
bool f[4096];
int p[3005];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&(p[i]));
if(p[1]<=p[n])
{
cout<<-1<<endl;
return 0;
}
f[p[1]^p[n]]=true;//执行到这条语句说明了从1号点是可以直接到n号点的,那么到达n号星球能量为p[1]^p[n]当然是可行的。
for(int i=2;i<=n-1;i++)枚举从1号点到n号点的中间点
{
if(p[i]<p[1]&&p[i]>p[n])如果1号点能到i号点,i号点能到n号点就要了
{
for(int j=0;j<=4095;j++ ) 拓展到达n号点时能量为0到4095的状态
f[j]=f[j]|f[j^p[i]];//f[j]是可行的话,说明不需要中间点i来拓展,否则的话则需要
,能不能拓展成功要看j^p[i]这个状态是否可行,如果j^p[i]状态可行的话,那么再往j^p[i]对应的路径里加入一个i号点,就可以得到到达n号点能量为j^p[i]^p[i],即j这个状态是可行的了。
}
}
for(int i=4095;i>=0;i--)
if(f[i])
{
cout<<i<<endl;
return 0;
}
}