题意:给出N个16进制的数,从中选出一个序列,问Σ j^(a[i]) 最大是多少,a[I]是选出来的数,j是这个数在序列中是第J个(从0开始计数)
范围:N<=10W,每个数小于256
解法:很明显的DP,DP[I][J]代表第I个数作为第J个数的最大值,很显然J如果是1到10W是会T的,但是发现每个数小于256,所以J也只要记录从0到255就好了(此时的J代表真实的J%256,因为J/256*256这部分是不会被异或到的),所以发现,DP[I][J]进行转移时,其值应该是过去的MAX{ DP[K][(J-1)%256] } +L^a[I] ,MAX值可以用一个数组随着更新进行记录, L 代表 比I小,且是最后一个%256=J 的数字,L尽可能大才能满足整体最优,这样就可以在O(256*10W)的复杂度内求解啦。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
ll dp[100100][256];
ll a[100100],n;
ll maxx[256];
ll sum[444];
ll val[444];
int main(){
val[0]=0;
sum[0]=0;
rep(i,1,420){
val[i]=val[i-1]+256;
sum[i]=sum[i-1]+val[i-1];
}
scanff(n);
rep(i,1,n){
int x;
scanf("%X",&x);
a[i]=ll(x);
}
mem(dp,-1);
mem(maxx,-1);
maxx[255]=0;
rep(i,1,n){
rep(j,0,255){
int k=j-1;
if(k==-1)k=255;
if(maxx[k]==-1)continue;
int t=i/256;
if(t*256+j+1>i)t--;
dp[i][j]=maxx[k]+((t*256+j)^a[i]);
}
rep(j,0,255)maxx[j]=max(maxx[j],dp[i][j]);
}
ll ans=0;
rep(i,1,n){
rep(j,0,255){
if(dp[i][j]>=0)ans=max(dp[i][j],ans);
}
}
printf("%lld\n",ans);
return 0;
}