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;
    }
    /*
    */
    
  • 相关阅读:
    call和apply的区别
    淘宝镜像(cnpm)的安装和使用
    文件包含漏洞
    vue简单的日历
    微信小程序(mpvue)—解决视频播放bug的一种方式
    vue 异步组件
    vuex的学习笔记
    vue2.0 添加监听滚动事件
    jquery tmpl生成导航
    vue 控制视图
  • 原文地址:https://www.cnblogs.com/valk3/p/12970996.html
Copyright © 2011-2022 走看看