1. 程式人生 > >【動態規劃】 Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

【動態規劃】 Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

and main spa def esp 動態 return 價值 can

劃分那個序列,沒必要完全覆蓋原序列。對於劃分出來的每個序列,對於某個值v,要麽全都在該序列,要麽全都不在該序列。

一個序列的價值是所有不同的值的異或和。整個的價值是所有劃分出來的序列的價值之和。 求整個的價值的最大值 f(i)表示最後一個劃分序列的右端點為i時,1~i的答案。 f(i)=max{max{f(j)}(1<=j<i)+xorsum(j+1,i)(j+1到i的區間合法)}(1<=i<=n) 需要在轉移的時候,順便處理f(i)的前綴max。 最終的答案就是所有f(i)的最大值。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,a[5010],f[5010],fpremax[5010],num[5010],cnts[5010];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		++num[a[i]];
	}
	for(int i=1;i<=n;++i){
		int no=0,xorsum=0;
		memset(cnts,0,sizeof(cnts));
		for(int j=i;j>=1;--j){
			if(!cnts[a[j]]){
				xorsum^=a[j];
				++no;
			}
			++cnts[a[j]];
			if(cnts[a[j]]==num[a[j]]){
				--no;
			}
			if(!no){
				f[i]=max(f[i],fpremax[j-1]+xorsum);
			}
		}
		fpremax[i]=max(fpremax[i-1],f[i]);
	}
	printf("%d\n",fpremax[n]);
	return 0;
}

【動態規劃】 Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip