链接:https://ac.nowcoder.com/acm/contest/317/C
来源:牛客网
示例1
输入
复制
3
457 456 23
输出
复制
478
说明
事例2
输入
复制
4
2 4 4 2
输出
复制
-1
示例3
输入
复制
5
234 233 123 2333 23
输出
复制
253
备注:
1⩽n,∀pi⩽3000
这道题就是一道简单dp。也不用背包。不过背包也能做。
很多人的方法是不对的,因为异或的性质,当前最大不一定异或了别人也大。后来样例加强了,但也只是加强了一点点。
我起初用的二维dp,int型的会超内存,改成bool才可以,但是那种方法会超时。
后来仔细想了下,简化成了一维。
很简单,就是dp【i】表示当前可不可以达到。
因为一定是由1走向n的,所以1和n肯定都要走。这就是我开始为什么把dp[beginn^endd]=1初始化的原因。其余的点就是在去重,和小于1,大于n的点中选。
循环一下就好了。
可能有人看了第二个代码会有疑问,为什么第一维可以省略。其实我在合法的cnt个点中选了若干个,他们一定是可以有唯一一种顺序相到达的。而我不用考虑这种顺序,我只是要求最大的值是谁。嗯。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=100000;
int dp[7010];
int a[3010],b[3010];
int cmp(int a,int b){
return a>b;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
int beginn=b[1];
int endd=b[n];
if(beginn<=endd){
printf("-1\n");
continue;
}
sort(b+1,b+1+n,cmp);
int cnt=1;
a[1]=beginn;
for(int i=2;i<=n;i++){
if(b[i]!=b[i-1] && b[i]<beginn &&b[i]>endd){
cnt++;
a[cnt]=b[i];
}
}
n=cnt;
memset(dp,0,sizeof(dp));
dp[beginn^endd]=1;
int maxx=beginn^endd;
for(int i = 2;i <= cnt;i++){
for(int j = 0;j < 7000;j++){
dp[j^a[i]] |= dp[j];
if(dp[j^a[i]]==1)
maxx=max(maxx,j^a[i]);
if(dp[j]==1){
maxx=max(maxx,j);
}
}
}
if((maxx==0)||(maxx==-1)){
printf("-1\n");
}
else
printf("%d\n",maxx);
}
return 0;
}
最开始的二维代码(超时)
我的第一个就是在第二个的基础上做的优化。(天天做水题的我。。)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=100000;
bool dp[3010][4100];
int a[3010],b[3010];
int cmp(int a,int b){
return a>b;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
a[1]=b[1];
sort(b+1,b+1+n,cmp);
int cnt=1;
for(int i=2;i<=n;i++){
if(b[i]!=b[i-1] && b[i]<a[1]){
cnt++;
a[cnt]=b[i];
}
}
n=cnt;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){
dp[i][a[1]]=1;
}
int maxx=-1;
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
for(int k=0;k<=4095;k++){
if(dp[j][k]==1){///到了i,当前异或值为k有没有
dp[i][k^a[i]]=1;
/// cout<<"k:"<<k<<" a[i]:"<<a[i]<<" "<<(k^a[i])<<endl;
if(i==n)
maxx=max(maxx,(k^a[i]));
}
}
}
}
if((maxx==0)||(maxx==-1)){
printf("-1\n");
}
else
printf("%d\n",maxx);
}
return 0;
}