这道题的减枝很好。如果是我自己写肯定不会写这样的减枝。这个减枝主要是剪掉了连续的两次异或的所有情况。
代码如下:
#include<cstdio>
using namespace std;
int b[50],p[50],k[50];
__int64 ans;
int n,u,r;
void dfs(int step,int a[],int way){
int a1[50];
if((u-step)%2==0){
__int64 cnt=0;
for(int i=0;i<=n-1;i++){
cnt+=a[i]*k[i];
}
if(cnt>ans)ans=cnt;
if(u==step)
return;
}
if(way){
for(int i=0;i<=n-1;i++)
a1[i]=a[i]^b[i];
dfs(step+1,a1,0);
}
for(int i=0;i<=n-1;i++)
a1[i]=a[p[i]]+r;
dfs(step+1,a1,1);
return;
}
main(){
int a[50];
while(scanf("%d%d%d",&n,&u,&r)!=-1){
ans=-100000000001;
// ans=0;
for(int i=0;i<=n-1;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<=n-1;i++){
scanf("%d",&b[i]);
}
for(int i=0;i<=n-1;i++){
scanf("%d",&k[i]);
}
for(int i=0;i<=n-1;i++){
scanf("%d",&p[i]);
p[i]--;
}
dfs(0,a,1);
printf("%I64d\n",ans);
}
}