zoukankan      html  css  js  c++  java
  • cf 811c Vladik and Memorable Trip

    原题链接:http://codeforces.com/contest/811/problem/C

    题意:将数组中的连续数字连成若干个“线段”(或者不连),其实就是区间。区间必须满足对于其中的任意数字,能够覆盖数组中的所有相等数字,比如对数组:1, 2, 5, 2 ,5,    [2, 5 ,2 ,5]是满足条件的区间,而[2, 5, 2]不是,因为它并没有包含所有的5.

    题目求不相交的满足条件的区间内不同数字的异或和的最大值。

    思路:这是一道普通的DP题,类似最长上升子序列,先求出每个数字的最长区间(左右端点),再定义dp[i]为左端点为1, 长度为i的区间所能得到的最大异或和。则dp[i]= dp[j-1]+res, j是被包含在[1, i]的满足条件的区间的左端点,res是对应的异或和。这么dp下去就好了。

    看别人的题解时自己尝试了一下,dp部分是枚举所有满足条件的区间,WA了。思考后发现,这么做有个错误,事实上第一步求出来的区间不一定是对的,没有保证在区间内和区间外同时出现同一个数字(也就是不满足条件的)。而枚举数字的位置可以在上述情况发生(或者说,对应区间不在[1, i]内)时停止枚举。具体实现见代码。

    AC代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;  
    const int MAXN = 5005;     
    int num[MAXN],dp[MAXN]; 
    struct Edge{
        int l,r;
    }edge[MAXN]; 
    bool vis[MAXN];  
    int main()  
    {  
        int n,m;
        scanf("%d",&n);  
        dp[0]=0;
        for(int i=0;i<MAXN;i++) edge[i].l=edge[i].r=0; 
        for(int i = 1 ; i <= n ; ++i)  
        {  
            scanf("%d",&num[i]);  
            m=num[i];
            if(!edge[m].l)edge[m].l = i;  
            edge[m].r = i;  
        }  
        for(int i = 1 ; i <= n ; ++i)  
        {  
            dp[i] = dp[i-1];  
            memset(vis,0,sizeof(vis));  
            int st = edge[num[i]].l;
            int res = 0;  
            for(int j = i ; j >= 1 ; --j)  
            {  
                if(!vis[num[j]])  
                {  
                    if(edge[num[j]].r>i)break;  //对应区间不在[1, i]内,停止枚举
                    st = min(st,edge[num[j]].l);  
                    res^=num[j];  
                    vis[num[j]] = 1;  
                }  
                if(j<=st)dp[i] = max(dp[i] , dp[j-1]+res);//维护区间最值  
            }  
        }  
        printf("%d
    ",dp[n]);  
    }  
  • 相关阅读:
    sqli-libs(38-41(堆叠注入)关)
    Vue 短信验证码逻辑
    promise(二)
    js类型转换
    微信小程序的组件传值
    微信小程序首页跳转详情页
    微信小程序的事件绑定
    微信小程序简介
    webpack4入门教程十分钟上手指南
    Vue 全局注册组件和局部注册组件
  • 原文地址:https://www.cnblogs.com/MasterSpark/p/7449068.html
Copyright © 2011-2022 走看看