Http://acm.tju.edu.cn/toj/showp4095.html
Question:
N items, n <= 30, each with weight W [I], W [I] <= 10 ^ 9, and D is missing, determine whether there are multiple solutions and no solutions. The number of items that are output by the unique solution is smaller.
Analysis:
If the weight is not that big, it is a simple backpack, and this data range cannot be stored in the backpack status. Then I searched for it, and TLE kept fighting .. In fact, the subsequent search strategies have been optimized well. Only half of the layers are searched, and then the sum of the searched set and the sum of the complementary set determine whether the sum is equal to D. However, this still cannot escape the number of C (15, 30) States.
Ask the senior to obtain a division algorithm .. Semi-processing, enumeration and not selecting, respectively, are 2 ^ 15, and then sort. For a value on one side, find whether there is a value on the other side so that they can sum up to D. Complexity: O (2 ^ (n/2) lg (2 ^ (n/2 )))
After that, I wa several times. On the one hand, my writing was failed. On the other hand, I didn't know whether the question was trick. One is the range of D. If Longlong is not enabled, it may burst when it is read. The other is that W [I] and D may be 0, then, I am dizzy when the value is 0 .. The program is AC ..
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 struct arr{ 7 int num; 8 long long sum; 9 } a[100000], b[100000]; 10 int T, n, sizea, sizeb; 11 long long D, w[40]; 12 bool legal[40]; 13 bool cmp(arr a, arr b) 14 { 15 return a.sum < b.sum; 16 } 17 int main() 18 { 19 scanf("%d", &T); 20 int cas = 0; 21 while(T--) 22 { 23 scanf("%d %lld", &n, &D); 24 for (int i = 0; i < n; i++) scanf("%lld", w+i); 25 sizea = sizeb = 1; 26 a[0].num = b[0].num = a[0].sum = b[0].sum = 0; 27 for (int i = 0; i <= n/2; i++){ 28 int tmp = sizea; 29 for (int j = 0; j < tmp; j++){ 30 a[sizea].num = a[j].num + 1; 31 a[sizea++].sum = a[j].sum + w[i]; 32 } 33 } 34 for (int i = n/2+1; i < n; i++){ 35 int tmp = sizeb; 36 for (int j = 0; j < tmp; j++){ 37 b[sizeb].num = b[j].num + 1; 38 b[sizeb++].sum = b[j].sum + w[i]; 39 } 40 } 41 sort(a, a+sizea, cmp); 42 sort(b, b+sizeb, cmp); 43 int count = 0, ans; 44 memset(legal, 0, sizeof(legal)); 45 for (int i = 0; i < sizea; i++){ 46 if (a[i].sum > D || count > 1) break; 47 if (a[i].sum == D){ 48 int number = a[i].num; 49 if (!legal[number]){ 50 legal[number] = true; 51 count ++; 52 ans = number; 53 } 54 } 55 if (a[i].sum <= D){ 56 long long need = D - a[i].sum; 57 int l = 0, r = sizeb-1, pos = -1; 58 while (l <= r) 59 { 60 int mid = (l + r) >> 1; 61 if (b[mid].sum == need){ 62 pos = mid; 63 break; 64 } 65 else if (b[mid].sum < need) l = mid + 1; 66 else r = mid - 1; 67 } 68 if (pos != -1){ 69 int tmp = pos; 70 while(pos < sizeb && b[pos].sum == b[tmp].sum){ 71 int number = a[i].num + b[pos].num; 72 if (!legal[number]){ 73 legal[number] = true; 74 count ++; 75 ans = number; 76 } 77 pos ++; 78 } 79 pos = tmp-1; 80 while(pos >= 0 && b[pos].sum == b[tmp].sum){ 81 int number = a[i].num + b[pos].num; 82 if (!legal[number]){ 83 legal[number] = true; 84 count ++; 85 ans = number; 86 } 87 pos --; 88 } 89 90 } 91 } 92 } 93 cas ++; 94 printf("Case #%d: ", cas); 95 if (count == 0) printf("IMPOSSIBLE\n"); 96 else if (count > 1) printf("AMBIGIOUS\n"); 97 else printf("%d\n", ans); 98 } 99 return 0;100 }