题目描述
小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
备注:
1⩽n,∀pi⩽3000
是不是全世界都想到了DP就我只想到了DFS?!!!!!
(痛楚我兴奋,停下我无法)
————————————————————————
1.0版本时有可能有忽略的地方,同时可能牛客数据太弱,上去一发就过了ヽ(・_・;)ノ
由于是因为这道题总是A不掉造成的弱分,很不开心,所以当即更了一篇,直接把当时用来A掉代码贴上来了(数据更新后当然就过不了了)
在这里进行补充,把后来通过的思路整理一下,感谢看到我博客的错误还可以给评论指出来:
这个题我后来了解到似乎有用dfs做出来的dalao们,但是由于不晓得如何剪枝,我码的dfs通通超时,所以只好用dp
输入之后首先判断是否可以到达n号星球(即p[1]>p[n]是否成立)
如果成立令其作为初始值(可以保证至少可以登上该星球,并且若其他星球都登不上去,这也是最终值)
接下来是整理数据,将里面无法从1星球登上的、无法登上n星球的进行删除
(ps:如果可以的话,把重复数据删除更加省时)
接下来进行从大到小的排序(整理数据之后就是星球1最大,星球n最小了)
然后就是动态规划问题了,动态规划中与找最大值(同时保证数据一定大于0)
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int m;
int a[13010],b[13010];
int dp[13010];
bool cmp(int a, int b)
{
return a > b;
}
int main()
{
cin>>m;
memset(dp, 0, sizeof(dp));
for(int i=1; i<=m; i++)
{
cin>>b[i];
}
if(b[1] <= b[m])
{
printf("-1\n");
return 0;
}
int ans = b[1] ^ b[m];
int n = 0;
for(int i=1; i<=m; i++)
{
if(b[i] >= b[1]) continue;
if(b[i] <= b[m]) continue;
a[++n] = b[i];
}
sort(a+1, a+1+n, cmp);
dp[ans] = 1;
int maxx = ans;
for(int i=1; i<=n; i++)
{
for(int j=maxx; j>=0; j--)
{
dp[j^a[i]] = max(dp[j^a[i]], dp[j]);
if(dp[j^a[i]])
{
maxx = max(maxx, j^a[i]);
}
}
}
printf("%d\n", maxx);
return 0;
}