Array:深搜加剪枝

    科技2022-08-13  86

    深搜加剪枝,剪枝根据两次异或以后值为本身来写

    #include<iostream> #include<stdio.h> using namespace std; #define sc scanf #define co cout #define e endl int maxx,n,m,t,floor; int b[30],c[30],d[30]; void update(int a[30]){ int tmp = 0; for(int i=1;i<=n;i++){ tmp += a[i] * c[i]; } //co<<tmp<<e; if(tmp>maxx) maxx = tmp; } void def(int count,int a[30],int aa[30],int flag){//flag代表进入当前节点前进行的操作 ,count第几次操作,a代表当前要传入的a数组的值,aa代表a上一步的操作的a的值 // 实际上aa数组只有操作1会用到,操作2的aa可以随便填 当传入的flag==1,下一次就没必要使用def(count+1,a,aa,1) 而是将这步操作省略,就是直接剪掉 // 操作0就是从根节点进入的时候还有连续两次操作1清空操作的时候使用 //在奇数层结束,更新奇数层的所有最大值,在偶数层结束,更新所有偶数层的最大值 //更新不能在开头更新 if(count==m){//叶节点必须更新,根节点进入且偶数次操作更新 update(a); return ; } if(count%2==floor||(count==0&&floor==0)){ //co<<"test"<<e; update(a); } if(flag==0){//更新操作1和操作2需要的a数组值 int a1[30],a2[30]; for(int i=1;i<=n;i++){//不论是根节点进入,还是连续两次1操作进入,都套用aa数组,根节点进入aa数组就是一开始的数组a a1[i] = aa[i] ^ b[i]; a2[i] = aa[d[i]] + t; } def(count+1,a1,aa,1); def(count+1,a2,aa,2); }else if(flag==1){//之前进行1操作 int a2[30]; for(int i=1;i<=n;i++){ a2[i] = a[d[i]] + t; } //def(count+1,a1,aa,1);1操作替换掉 //def(count+1,a,aa,0); 可以剪枝 def(count+1,a2,aa,2); }else if(flag==2){//之前进行2操作,其他操作按计划进行 int a1[30],a2[30]; for(int i=1;i<=n;i++){ a1[i] = a[i] ^ b[i]; a2[i] = a[d[i]] + t; } def(count+1,a1,aa,1); def(count+1,a2,aa,2); } return ; } int main(){ int a[30]; while(sc("%d %d %d",&n,&m,&t)!=EOF){//每次输入,重置奇数偶数层m判断,重置最大值 maxx = -100000000;//必须为该值,极端情况一个数操作一次,a是10000,c是-10000 floor = m%2; for(int j=1;j<=n;j++){ sc("%d",&a[j]); } for(int j=1;j<=n;j++){ sc("%d",&b[j]); } for(int j=1;j<=n;j++){ sc("%d",&c[j]); } for(int j=1;j<=n;j++){ sc("%d",&d[j]); } def(0,a,a,0); co<<maxx<<e; } return 0; }

     

    Processed: 0.016, SQL: 9