原题链接: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 = ;
int num[MAXN],dp[MAXN];
struct Edge{
int l,r;
}edge[MAXN];
bool vis[MAXN];
int main()
{
int n,m;
scanf("%d",&n);
dp[]=;
for(int i=;i<MAXN;i++) edge[i].l=edge[i].r=;
for(int i = ; 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 = ; i <= n ; ++i)
{
dp[i] = dp[i-];
memset(vis,,sizeof(vis));
int st = edge[num[i]].l;
int res = ;
for(int j = i ; j >= ; --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]] = ;
}
if(j<=st)dp[i] = max(dp[i] , dp[j-]+res);//维护区间最值
}
}
printf("%d\n",dp[n]);
}

cf 811c Vladik and Memorable Trip的更多相关文章

  1. CodeForces - 811C Vladik and Memorable Trip(dp)

    C. Vladik and Memorable Trip time limit per test 2 seconds memory limit per test 256 megabytes input ...

  2. Codeforces 811C Vladik and Memorable Trip (区间异或最大值) (线性DP)

    <题目链接> 题目大意: 给你n个数,现在让你选一些区间出来,对于每个区间中的每一种数,全部都只能出现在这个区间. 每个区间的价值为该区间不同的数的异或值之和,现在问你这n个数最大的价值是 ...

  3. CodeForces 811C Vladik and Memorable Trip

    $dp$. 记录$dp[i]$表示以位置$i$为结尾的最大值. 枚举最后一段是哪一段,假设为$[j,i]$,那么可以用$max(dp[1]...dp[j-1]) + val[j][i]$去更新$dp[ ...

  4. CodeForce-811C Vladik and Memorable Trip(动态规划)

    Vladik and Memorable Trip CodeForces - 811C 有一个长度为 n 的数列,其中第 i 项为 ai. 现在需要你从这个数列中选出一些互不相交的区间,并且保证整个数 ...

  5. Codeforces 811 C. Vladik and Memorable Trip

    C. Vladik and Memorable Trip   time limit per test 2 seconds memory limit per test 256 megabytes inp ...

  6. C. Vladik and Memorable Trip DP

    C. Vladik and Memorable Trip time limit per test 2 seconds memory limit per test 256 megabytes input ...

  7. C. Vladik and Memorable Trip 解析(思維、DP)

    Codeforce 811 C. Vladik and Memorable Trip 解析(思維.DP) 今天我們來看看CF811C 題目連結 題目 給你一個數列,一個區段的數列的值是區段內所有相異數 ...

  8. Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

    http://codeforces.com/contest/811/problem/C 题意: 给出一行序列,现在要选出一些区间来(不必全部选完),但是相同的数必须出现在同一个区间中,也就是说该数要么 ...

  9. 【动态规划】 Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

    划分那个序列,没必要完全覆盖原序列.对于划分出来的每个序列,对于某个值v,要么全都在该序列,要么全都不在该序列.  一个序列的价值是所有不同的值的异或和.整个的价值是所有划分出来的序列的价值之和.   ...

随机推荐

  1. python杂谈

    1.for循环过界保护 例如: a=len([1,2,3]) for i in range(a): for j in range(i+1:a) print(i,j) 不会报错 2.python集合和列 ...

  2. 16/8/21_PHP-有关类函数,this,static,面向对象思想介绍

    class_exists():判断某个类是否存在(定义过) interface_existe():判断接口是否存在 get_class():获取某个对象的"所属类名" get_pa ...

  3. JSP表单提交 与 接受显示

    Demo01.jsp 提交表单输入的信息至 Demo02.jsp方法一 1 <%@ page language="java" contentType="text/h ...

  4. vue事件的绑定

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Marriage Match II 【HDU - 3081】【并查集+二分答案+最大流】

    题目链接 一开始是想不断的把边插进去,然后再去考虑我们每次都加进去边权为1的边,直到跑到第几次就没法继续跑下去的这样的思路,果不其然的T了. 然后,就是想办法咯,就想到了二分答案. 首先,我们一开始处 ...

  6. 软件体系结构-分层、代理、MVC、管道与过滤器

    什么是软件架构? 程序或计算系统的软件体系结构是系统的一个或多个结构,包括软件元素.这些元素的外部可见属性以及它们之间的关系. ——Software Engineering Institute(SEI ...

  7. 编程语言-Python2-问题整理

    InsecureRequestWarning: Unverified HTTPS request is being made. import urllib3 urllib3.disable_warni ...

  8. php跨域的几种方式

    PHP实现跨域的几种形式 1.JSONP(JSON with padding)原理 利用html里面script标签可以加载其他域下的js这一特性,使用script src的形式来获取其他域下的数据, ...

  9. pdo getLastInertID()无结果

    该函数只返回具有自增约素的表, 不然返回0. 使用exec()得到的是受影响的行数.

  10. 查询sqlserver中表信息

    ALTER PROCEDURE [dbo].[GetTableInfo] @tableName NVARCHAR(MAX) AS BEGIN SELECT -- CASE -- WHEN col.co ...