zoukankan      html  css  js  c++  java
  • Codeforces 811C

    Vladik often travels by trains. He remembered some of his trips especially well and I would like to tell you about one of these trips:

    Vladik is at initial train station, and now n people (including Vladik) want to get on the train. They are already lined up in some order, and for each of them the city code a i is known (the code of the city in which they are going to).

    Train chief selects some number of disjoint segments of the original sequence of people (covering entire sequence by segments is not necessary). People who are in the same segment will be in the same train carriage. The segments are selected in such way that if at least one person travels to the city x, then all people who are going to city x should be in the same railway carriage. This means that they can’t belong to different segments. Note, that all people who travel to the city x, either go to it and in the same railway carriage, or do not go anywhere at all.

    Comfort of a train trip with people on segment from position l to position r is equal to XOR of all distinct codes of cities for people on the segment from position l to position r. XOR operation also known as exclusive OR.

    Total comfort of a train trip is equal to sum of comfort for each segment.

    Help Vladik to know maximal possible total comfort.

    Input

    First line contains single integer n (1 ≤ n ≤ 5000) — number of people.

    Second line contains n space-separated integers a 1, a 2, …, a n (0 ≤ a i ≤ 5000), where a i denotes code of the city to which i-th person is going.

    Output

    The output should contain a single integer — maximal possible total comfort.

    Examples
    Input
    6
    4 4 2 5 2 3
    Output
    14
    Input
    9
    5 1 3 1 5 2 4 2 5
    Output
    9

    Note

    In the first test case best partition into segments is: [4, 4] [2, 5, 2] [3], answer is calculated as follows: 4 + (2 xor 5) + 3 = 4 + 7 + 3 = 14

    In the second test case best partition into segments is: 5 1 [3] 1 5 [2, 4, 2] 5, answer calculated as follows: 3 + (2 xor 4) = 3 + 6 = 9.

    题目大意:

    先输入一个数 n ,第二行输入n个数,表示第 i 个人想去的地点,你需要将其分成多个区间,不一定所有数都要选,区间必须满足以下条件:当前区间中存在的任何数不允许在其他地方出现。一个区间的舒适度等于区间内所有不同的数异或的结果,可以分成多个区间,输出舒适度和的最大值。

    解题思路:

    很明显的dp,先预处理一下该数在数组中出现的最左边和最右边的位置w,使w[a[i]][0] 表示a[i]的左端点,w[a[i]][1] 表示a[i]的右端点,dp[n] 则表示前n个人舒适度的最大值,从1开始往n枚举。一共有两种情况:

    • 如果该数要,则dp[i] = dp[j - 1] + 该数所在区间的舒适度val,j 为a[i] 左端点 - 1
    • 如果该数不要,则dp[i] = dp[i - 1]

    首先使dp[i] = dp[i - 1],判断一下a[i]的最右边的位置,如果a[i]右边的位置 > i ,则continue,该区间不能要,如果<= i ,则让 j = i,求一下a[i]的左端点st,之后从 j -> st,如果遇到a[j]的右端点 > i 的情况,则说明这个数右端点比 i 大,退出循环,如果a[j] 的左端点 < st 则说明该区间需要往左延长,更新一下st的值,最后判断 j 是不是等于st,如果等于 st ,则说明该区间是合法的,求一下最大值即可。暴力跑完 1 -> n之后输出 dp[n] 即可。

    Code:

    #pragma GCC optimize(2)
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N = 5050;
    int vis[N], a[N], dp[N];
    int w[N][2];
    int main()
    {
    	int n;
    	cin >> n;
    	memset(dp, 0, sizeof dp);//全部初始化为0
    	memset(w, 0, sizeof w);
    	for (int i = 1; i <= n; i ++)
    	{
    		cin >> a[i];
    		if (!w[a[i]][0])  w[a[i]][0] = i;//预处理a[i] 第一次出现和最后一次出现的位置
    		w[a[i]][1] = i;
    	}
    	for (int i = 1; i <= n; i ++)//暴力从 1 跑到 n
    	{
    		dp[i] = dp[i - 1];
    		if (w[a[i]][1] > i)  continue;//如果该数的右端点 > i 则说明不能放在这个区间,需要continue
    		int val = a[i], st = w[a[i]][0];//从j跑到 a[i]的左端点
    		memset(vis, false, sizeof vis);
    		int j;
    		vis[a[i]] = i;//该数已经走过以后就不用异或了
    		for (j = i; j > st; j --)
    		{
    			if (vis[a[j]])  continue;//如果走过则可以跳过
    			vis[a[j]] = true;
    			if (w[a[j]][1] > i)  break;//如果a[j]的右端点 > i 则说明a[j]不能放在这个区间,需要放在大区间
    			if (w[a[j]][0] < st)  st = w[a[j]][0];//如果发现更左的端点则需要更新一下端点
    			val ^= a[j];
    		}
    		if (j == st)  dp[i] = max(dp[i - 1], dp[j - 1] + val);//说明该区间合法
    	}
    	cout << dp[n] << endl;
    	return 0;
    }
    
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    开源数据库在平安的应用实践
    从Oracle到PostgreSQL:Storage Index 特性 vs BRIN 索引
    Cosmos 白皮书
    基于支付场景下的微服务改造与性能优化
    MySQL数据库备份之主从同步配置
    Maven Gradle 区别
    荐书:《PostgreSQL指南:内幕探索》| 留言送书
    SQL、NoSQL、NewSQL,论开源之路谁主沉浮
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294169.html
Copyright © 2011-2022 走看看