cf的每个dp题,都有它的特点吧,这个dp就很有特点,但是不难,也没什么好说的..
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+5;
int dp[N],a[N],w[N],e[N];
bool mp[N];
//dp[i]表示1~i这段最大的值,a[]数组就是题目给定的,然后w[i]存每个值最左边的位子,e[i]存每个值右边的位子.
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<=5000;i++) w[i]=5001,e[i]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
w[a[i]]=min(w[a[i]],i);//最左边
// cout<<w[a[i]]<<endl;
e[a[i]]=max(e[a[i]],i);//最右边
}
int st;
for(int i=1;i<=n;i++)
{
dp[i]=dp[i-1];
int res=0;
memset(mp,false,sizeof mp);
st=i;
for(int j=i;j>0;j--)
{
// cout<<j<<' '<<a[j]<<' '<<e[a[j]]<<' '<<w[a[j]]<<endl;
if(e[a[j]]>i) break;
// if(w[a[j]]<j) continue;
if(!mp[a[j]]) res^=a[j];
mp[a[j]]=true;
if(w[a[j]]<j||j>st) {st=min(w[a[j]],st); continue;}
dp[i]=max(dp[j-1]+res,dp[i]);
}
//cout<<dp[i]<<endl;
}
printf("%d\n",dp[n]);
return 0;
}
/*
5
1558 4081 3591 1700 3232
*/

京公网安备 11010502036488号