• cf811C(预处理&dp)


    题目链接: http://codeforces.com/problemset/problem/811/C

    题意: 给一个有n个人排队上车,去相同地方的人要么坐在同一个车厢,要不就不上车,问最大舒适度和是多少。苏适度是车厢内所有数组成的集合的异或值。

    即: 给你n个数,现在让你选一些区间出来,对于每个区间中的每一种数,全部都要出现在这个区间。 每个区间的价值为该区间不同的数的异或值,现在问你这n个数最大的价值是多少。

    注意: 相交的区间要么全选要么全不选

    思路: dp

    dp[i] 存储前 i (即 i 为元素 a[i] 所在区间的右边界)个人最大舒适度值, 对于当前 i , 从 i 往前更新一遍.

    动态转移方程式为: dp[i] = max(dp[i], dp[j] + ans) , 其中 ans 为合法区间 [j, i] 的舒适度.

    需要先预处理一下 a[i] 所在区间来判断选取区间时的合法性.

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 using namespace std;
     4 
     5 const int MAXN = 5e3 + 10;
     6 int s[MAXN], e[MAXN], a[MAXN], dp[MAXN];
     7 
     8 int main(void){
     9     int n;
    10     scanf("%d", &n);
    11     for(int i = 1; i <= n; i++){
    12         scanf("%d", &a[i]);
    13         if(!s[a[i]]) s[a[i]] = i;
    14         e[a[i]] = i;
    15     }
    16     for(int i = 1; i <= n; i++){
    17         dp[i] = dp[i -1];
    18         int vis[MAXN] = {0,};
    19         int cnt = s[a[i]], ans = 0;
    20         for(int j = i; j > 0; j--){
    21             if(!vis[a[j]]){
    22                 if(e[a[j]] > i) break;
    23                 cnt = min(cnt, s[a[j]]);
    24                 ans ^= a[j];
    25                 vis[a[j]] = 1;
    26             }
    27             if(j == cnt) dp[i] = max(dp[i], dp[j - 1] + ans);
    28         }
    29     }
    30     printf("%d
    ", dp[n]);
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    idea配置tomcat
    idea中配置tomcat乱码问题--记录处理经验
    svn提交报错值 remains tree in conflict
    Vue之MVVM
    python 时间日期处理
    SVN使用指南
    linux查看硬件信息
    软件集成过程标准化的建议
    术语辨析
    科学计数e+转成正常str
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7123889.html
Copyright © 2020-2023  润新知