原题链接: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. JSONP的产生,和ajax的异同!

    先说说JSONP是怎么产生的: 其实网上关于JSONP的讲解有很多,但却千篇一律,而且云里雾里,对于很多刚接触的人来讲理解起来有些困难,着用自己的方式来阐释一下这个问题,看看是否有帮助. 1.一个众所 ...

  2. JSP_01

    1.定义局部变量.输出语句 <!doctype html> <html> <head> <title>定义局部变量.输出语句</title> ...

  3. 2019/10/13 TZOJ

    水题虽不好,但是很爽 渴望未来某天能把剩下的题补了,先做个记录. Hard Disk Drive http://acm.hdu.edu.cn/showproblem.php?pid=4788 单位转化 ...

  4. Android深度探索-卷1第五章心得体会

    S3C6410是由三星公司推出的一款低功耗.高性价比的RISC处理器,开发是,首先安装minicom串口调试工具: 第一步:检测当前系统是否支持USB转串口. Lsmod | grep usseria ...

  5. Oracle基本操作练习(一)

    --创建表空间 create tablespace test datafile 'c:\test.dbf' size 100m autoextend on next 10m; --删除表空间 drop ...

  6. Netty内存管理器ByteBufAllocator及内存分配

    ByteBufAllocator 内存管理器: Netty 中内存分配有一个最顶层的抽象就是ByteBufAllocator,负责分配所有ByteBuf 类型的内存.功能其实不是很多,主要有以下几个重 ...

  7. MySQL-第五篇视图

    1.视图看上去像是表,但它又不是,它并不能存储数据.视图只是一个或者多个表的逻辑显示.使用视图的好处: 1>可以限制对数据的访问 2>可以使复杂的查询变得简单 3>提供了数据的独立性 ...

  8. 使用form提交到搜狗浏览器示例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 缓存模块redis

    1.安装 安装 下载 :wget http://download.redis.io/releases/redis-3.2.8.tar.gz 解压:tar xzf redis-3.2.8.tar.gz ...

  10. C#面试 笔试题 三

    1.传入某个属性的set方法的隐含参数的名称是什么? value,它的类型和属性所声名的类型相同.   2.C#支持多重继承么? 类之间不支持,接口之间支持.类对接口叫做实现,不叫继承. 3.C#中所 ...