Bidirectional search

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

Guess you like

Origin www.cnblogs.com/gn1314/p/11484819.html