codeforce 416 div2 C - Vladik and Memorable Trip 线性dp

这个dp自己想不到,,
记得之前的简单的线性dp 其实可以作为扩展

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.

**题意

给一个长度最大为5000的数组,每个数是0~5000之内的整数,现在要求选k段不相交的子线段,满足对于每一个数字,要么都没有被选,要么在同一段上(比如1,2,1,2,区间【1,3】=1,2,1就是不合法的,因为另外一个2不在这个子线段上),然后分数定义为每一段里所有不同数的异或(xor)相加,求最大的分数。**

2017年08月18日14:45:29在做还是不会。。

int l[N],r[N];
int vis[N];
int dp[N];
int a[N];
int main(){
    int n;
     //freopen("in.txt","r",stdin);
    sf("%d",&n);
    rep(i,1,n){sf("%d",&a[i]);if(!l[a[i]])l[a[i]]=i;r[a[i]]=i;}
    mem(dp,0);
    for(int i=1;i<=n;++i){
        mem(vis,0);
        dp[i]=dp[i-1];
        int pos=i;
       int tmp=0;
        for(int j=i;j>=1;--j){
            if(!vis[a[j]]){
                vis[a[j]]=1;
                if(r[a[j]]>i)break;
                pos=min(pos,l[a[j]]);
                tmp^=a[j];
            }
            if(j<=pos)dp[i]=max(dp[i],dp[j-1]+tmp);
        }
    }
    pf("%d\n",dp[n]);
}

你可能感兴趣的:(codeforce,简单基础经典dp)