题意:
有一列火车要拉人,把一群人放在不同的车厢,每一个车厢里面的人去的城市编号的
异或值和就是这列车的舒适度,问如何划分才能使得舒适度最大,输出最大值。
- 注意:有些人的目的城市相同,则需要在同一个车厢,有些人可以不上车。
思路:
dp[i] 表示1~i人坐车的最大值
那么怎么找到不同的段呢?我们可以从第i个人向前找某一个段,找到一个段的时候就
比较保存在dp[i]中,其中的问题有一个就是相同目的的人怎么办?
解决办法:预处理每一个城市的人在原序列的初始和结束位置。
dp的时候直接判断是否满足条件就行。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 5005;
int n;
int vis[maxn],dp[maxn];
int a[maxn],s[maxn],e[maxn];
int main()
{
//freopen("in.txt","r",stdin);
cin>>n;
for(int i = 1;i <= n; i++) {
cin>>a[i];
if(!s[a[i]]) {
s[a[i]] = i;
}
e[a[i]] = i;
}
for(int i = 1;i <= n; i++) {
dp[i] = dp[i-1];
int ans = 0;
int Min = s[a[i]];
memset(vis,0,sizeof(vis));
for(int j = i;j >= 1; j--) {
if(e[a[j]] > i)
break;
if(!vis[a[j]]) {
ans ^= a[j];
vis[a[j]] = true;
}
Min = min(Min,s[a[j]]);
if(Min >= j) {
dp[i] = max(dp[i],dp[j-1] + ans);
}
}
}
printf("%d\n",dp[n]);
return 0;
}