牛客训练营1-C(2.0)

题目描述

小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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值