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 */