zoukankan      html  css  js  c++  java
  • 【CF-811 C. Vladik and Memorable Trip】DP

    C. Vladik and Memorable Trip

    题意

    火车上有n个人,(a_i)表示第(i)个人要去的地方,可以画若干个不相交的线段,

    线段不一定覆盖所有的人,如果(x)在某个线段上,那么所有的(x)都要在这个

    线段上,一个线段的价值为出现在这个线段上不同数字的异或和,列车的

    价值为所有线段的价值和,问列车的最大价值。

    PS

    这是去年一场个人赛的题目,当时我用线段树写的,

    WA 到怀疑人生,其实就是忘记清空了。。。而且代码巨长,今天又做到了。

    思路

    因为是划分线段,很容易想到DP,(dp[i])表示在前i个人中划线段的最大价值。

    我们枚举以(i)为结尾的线段更新(dp[i])即可。

    注意:要保证以(i)为结尾的线段,满足题目中的条件是才可以更新(dp[i]),具体

    见代码。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    const int inf=0x3f3f3f3f;
    typedef long long ll;
    
    int arr[N],dp[N],minn[N],maxn[N];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&arr[i]);
            if(!minn[arr[i]])
                minn[arr[i]]=i;
            maxn[arr[i]]=i;
        }
        for(int i=1;i<=n;i++)
        {
            dp[i]=dp[i-1];
            int tmp=0,pos=minn[arr[i]];
            for(int j=i;j;j--)
            {
                pos=min(minn[arr[j]],pos);//更新当前线段中数字出现最早的位置
                //如果当前数字最晚出现的位置大于i,那么以i为结尾的线段不符合条件
                if(maxn[arr[j]]>i) break;
                //因为是不同,所以我们只在数字的最小位置进行异或
                if(minn[arr[j]]==j) tmp^=arr[j];
                //当已经遍历过的所有数字的最小位置==j时,才可以更新
                if(pos==j) dp[i]=max(dp[i],dp[j-1]+tmp);
            }
        }
        printf("%d
    ",dp[n]);
        return 0;
    }
    /*
    */
    
  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/valk3/p/12970996.html
Copyright © 2011-2022 走看看