Bidirectional search - each search starting from the general state of the initial state and the final state, generating two half the depth of the search tree, in the middle of the intersection, combined into a final answer
Example: gifts (cattle off network)
Subject description:
As punishment, GY were sent to help a sacred cow for girls gifts (GY: looks like a good job) but after seeing the gift GY, he would not think so.
A sacred cow with N gift, and extremely heavy, but the GY effort also extremely large (-_- b), once he could move in weight and w (w≤231-1) less
Any number of items. GY want to try some of the items once Bandiao heavy, you tell him in his effort to move the performance range of a maximum weight is.
Ideas:
The initial idea is to enumerate + binary compressed state, adding a variety of optimization, but the best case only by 88.78% of the sample, but can only see the big brother of AC codes.
AC Code ideas:
With the idea to write binary search dfs, c ++ added weight to the unique function to smooth over, and if not the same weight can only 88.78% of the sample, this time
You might think did not go wrong code is not heavy, in fact, go heavy, and heavy hand-written code, and unique to have tried, still wrong, because my memory
In the making of this question by a significant decline in ...... specific binary search dfs written in code, easy to understand
wrong codes:
1 #include <set> 2 #include <cstdio> 3 #include <algorithm> 4 #define LL long long 5 using namespace std; 6 7 LL w,A[10000005], B[10000005]; 8 int n, arr[50]; 9 10 bool cmp(int a,int b){ 11 return a>b; 12 } 13 14 inline LL find(LL k, int pos) { 15 int l = 1, r = pos; 16 int mid; 17 while (l < r) { 18 mid = (l + r + 1) >> 1; 19 if (A[mid] <= k) { 20 l = mid; 21 } 22 else { 23 r = mid - 1; 24 } 25 } 26 return A[l]; 27 } 28 29 int main(void) 30 { 31 scanf("%lld%d", &w, &n); 32 for (int i = 0; i < n; i++) 33 scanf("%d", &arr[i]); 34 sort(arr,arr+n,cmp); 35 36 LL res; 37 int m = n / 2+2, num = 0,flag; 38 for (int i = 0; i < (1 << m); ++i) { 39 flag = res = 0; 40 for (int j = 0; j < m; ++j) { 41 if (i & (1 << j)) 42 res += arr[j]; 43 if(res>w){ 44 flag=1; 45 break; 46 } 47 } 48 if(!flag) 49 //s.insert(res); 50 A[++num]=res; 51 } 52 sort(A+1,A+1+num); 53 /*int p=2,nidx=2; 54 while(p<=num){ 55 if(A[p]!=A[nidx-1]){ 56 A[nidx]=A[p]; 57 nidx++; 58 p++; 59 } 60 else 61 p++; 62 } 63 num=nidx-1; 64 */ 65 unique(A+1,A+1+num); 66 67 int cnt = 0, r = n - m; 68 for (int i = 0; i < (1 << r); ++i) { 69 flag = res = 0; 70 for (int j = 0; j < r; ++j) { 71 if (i & (1 << j)) 72 res += arr[m + j]; 73 if(res>w){ 74 flag=1; 75 break; 76 } 77 } 78 if(!flag) 79 B[++cnt]=res; 80 } 81 //sort(B+1,B+1+cnt); 82 83 /*p=2,nidx=2; 84 while(p<=cnt){ 85 if(B[p]!=B[nidx-1]){ 86 B[nidx]=B[p]; 87 nidx++; 88 p++; 89 } 90 else 91 p++; 92 } 93 cnt=nidx-1;*/ 94 //unique(B+1,B+1+cnt); 95 96 LL ans = 0; 97 for (int i = 1; i <= cnt; ++i) { 98 if (B[i] == w) { 99 ans = w; 100 break; 101 } 102 else if (A[2] > w - B[i]) { 103 ans = max(ans, B[i]); 104 } 105 else { 106 ans = max(ans, B[i] + find(w - B[i], num)); 107 } 108 } 109 printf("%lld\n", ans); 110 111 return 0; 112 }
Wherein commented handwritten deduplication code, and a set, map to a variety of heavy, or even longer
AC Code:
1 #include <cstdio> 2 #include <algorithm> 3 #define LL long long 4 using namespace std; 5 6 LL acnt,w; 7 int n,deep; 8 LL res,arr[50],A[10000005]; 9 10 bool cmp(LL a,LL b){ 11 return a>b; 12 } 13 14 void dfs1(int nd,LL sum){ 15 if(nd==deep+1){ 16 A[++acnt]=sum; 17 return; 18 } 19 dfs1(nd+1,sum); 20 if(sum+arr[nd]<=w) 21 dfs1(nd+1,sum+arr[nd]); 22 } 23 24 void cal(LL x){ 25 LL k=w-x; 26 int l=1,r=acnt,mid; 27 while(l<r){ 28 mid=(l+r+1)>>1; 29 if(k>=A[mid]) 30 l=mid; 31 else 32 r=mid-1; 33 } 34 if(x+A[l]<=w) 35 res=max(res,x+A[l]); 36 } 37 38 void dfs2(int nd,LL sum){ 39 if(nd==n+1){ 40 cal(sum); 41 return ; 42 } 43 dfs2(nd+1,sum); 44 if(sum+arr[nd]<=w) 45 dfs2(nd+1,sum+arr[nd]); 46 } 47 48 int main(void) 49 { 50 scanf("%lld%d",&w,&n); 51 for(int i=1;i<=n;++i) 52 scanf("%lld",&arr[i]); 53 sort(arr+1,arr+1+n,cmp); 54 55 deep=n/2+2; 56 dfs1(1,0); 57 sort(A+1,A+1+acnt); 58 acnt=unique(A+1,A+acnt+1)-(A+1); 59 dfs2(deep+1,0); 60 printf("%lld\n",res); 61 62 return 0; 63 }
Wherein Find w-sum is smaller than the maximum number of time saving with binary lookup