Codeforces 811C Vladik and Memorable Trip DP

来源:互联网 发布:mac网络图标 编辑:程序博客网 时间:2024/05/21 17:50

点击打开链接

题意:n个数a[i],定义区间[l,r]舒适度为[l,r]内不相同数异或和,要求选出若干条不相交的区间,使得舒适度最大.

要求若a[i]被选中 则所有和a[i]相等的数必须在同一区间 n,a[i]<=5000 

设dp[i]为前i数能选出的最大值. l(x),r(x)为x第一次和最后一次出现的位置

如果能选a[i]结尾的合法区间即r[a[i]]=i  dp[i]=dp[L-1]+sum(L,i)  L=min(L,l[a[j]) && r[j] <i   .a[i])<=j<=r(a[i]) 

否则不考虑a[i] dp[i]=dp[i-1]

#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<ll,ll> ii;const int N=2e5+20;const ll inf=1e11;const double eps=1e-11;int n,a[N],l[N],r[N],vis[N];int dp[N];int sum(int l,int r){int res=0;memset(vis,0,sizeof(vis));for(int i=l;i<=r;i++){if(!vis[a[i]])vis[a[i]]=1,res^=a[i];}return res;}int main(){while(cin>>n){for(int i=0;i<=5000;i++)l[i]=1e5,r[i]=0;for(int i=1;i<=n;i++){scanf("%d",&a[i]);l[a[i]]=min(l[a[i]],i);r[a[i]]=max(r[a[i]],i);}memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++){int x=a[i];dp[i]=dp[i-1];if(r[x]==i)//是否有以a[i]结尾的区间 {int L=l[x];bool flag=true;for(int j=l[x];j<=r[x];j++){if(r[a[j]]>i)flag=false;L=min(L,l[a[j]]);}if(flag)dp[i]=max(dp[i],dp[L-1]+sum(L,i));}}cout<<dp[n]<<endl;}return 0;}




阅读全文
0 0
原创粉丝点击