zoukankan      html  css  js  c++  java
  • codeforces 811 C. Vladik and Memorable Trip(dp)

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

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

    题解:一般这种说法的题目都是用dp的,然后显然设dp[i]表示前i个能取得的最大价值,然后再存一下每个数的起始位置和

    结束位置然后n*n就可以了,具体看一下代码,挺短的。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 5e3 + 10;
    int a[M] , ft[M] , ed[M] , dp[M] , vis[M];
    int main() {
        int n;
        scanf("%d" , &n);
        memset(ft , inf , sizeof(ft));//表示的是数字i开始的位置
        memset(ed , 0 , sizeof(ed));//表示的是数字i结束的位置
        for(int i = 1 ; i <= n ; i++) {
            scanf("%d" , &a[i]);
            ft[a[i]] = min(ft[a[i]] , i);
            ed[a[i]] = max(ed[a[i]] , i);
        }
        memset(dp , 0 , sizeof(dp));
        for(int i = 1 ; i <= n ; i++) {
            dp[i] = dp[i - 1];
            memset(vis , 0 , sizeof(vis));
            int sum = 0 , st = i;
            for(int j = i ; j >= 1 ; j--) {
                if(!vis[a[j]]) {
                    if(ed[a[j]] > i) break;
                    st = min(st , ft[a[j]]);
                    sum ^= a[j];
                    vis[a[j]] = 1;
                }
                if(st >= j) dp[i] = max(dp[i] , dp[j - 1] + sum);//显然当取到的数最小的位置小于等于j时这一串是可以合并的这种递推方法是可以求得所有可能性的
            }
        }
        printf("%d
    " , dp[n]);
        return 0;
    }
    
  • 相关阅读:
    kuangbin_ShortPath K (POJ 3159)
    kuangbin_ShortPath I (POJ 2240)
    kuangbin_ShortPath H (POJ 3660)
    kuangbin_ShortPath G (POJ 1502)
    kuangbin_ShortPath J (POJ 1511)
    kuangbin_ShortPath F (POJ 3259)
    kuangbin_ShortPath E (POJ 1860)
    StoryBoard中使用xib
    iOS APP 架构漫谈[转]
    Mac 快速修改 hosts 文件
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6929468.html
Copyright © 2011-2022 走看看