[TYVJ2340 送礼物] 双向搜索

题目限制

时间限制 内存限制 评测方式 题目来源
1000ms 131072KiB 标准比较器 Local

题目描述

作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了。某神牛有N个礼物,且异常沉重,但是GY的力气也异常的大(-_-b),他一次可以搬动重量和在w(w<=2^31-1)以下的任意多个物品。GY希望一次搬掉尽量重的一些物品,请你告诉他在他的力气范围内一次性能搬动的最大重量是多少。

输入格式

第一行两个整数,分别代表W和N。
以后N行,每行一个正整数表示G[i],G[i]<= 2^31-1。

输出格式

仅一个整数,表示GY在他的力气范围内一次性能搬动的最大重量。

提示

对于20%的数据 N<=26
对于40%的数据 W<=2^26


提交地址:joyoi

题解:

双向搜索, 先搜一半, 把那一半的所有拼出来的值放入数组t;

然后另一半,搜出一个值的时候在 t 中二分出<=w-now的最大的一个;

然后去更新ans;

数据太坑老是TLE;找不出原因

80分代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 #define int long long
 6 
 7 inline int read()
 8 {
 9     int res=0;bool fl=0;char ch=getchar();
10     while(!isdigit(ch)){if(ch=='-')fl=1;ch=getchar();}
11     while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch-'0');ch=getchar();}
12     return fl?-res:res;
13 } 
14 
15 int w, n;
16 int a[50];
17 int t[10000010], top;
18 int ans;
19 
20 inline void dfs(int sum, int stp, int dep)
21 {
22     if (sum > w) return;
23     if (stp > dep) {t[++top] = sum;return;}
24     dfs(sum + a[stp], stp+1, dep);
25     dfs(sum, stp+1, dep);
26 }
27 
28 inline void dfs2(int sum, int stp, int dep)
29 {
30     if (sum > w) return;
31     if (stp > dep)
32     {
33         int l = 1, r = top, mid;
34         while (l < r)
35         {
36             mid = l + r + 1 >> 1;
37             if (t[mid] <= w - sum) l = mid;
38             else r = mid - 1; 
39         }
40         int tmp = sum + t[l];
41         if (tmp > w or tmp < 0) return;
42         ans = max(ans, sum + t[l]);
43         return;
44     }
45     dfs2(sum + a[stp], stp+1, dep);
46     dfs2(sum, stp+1, dep);
47 }
48 
49 signed main()
50 {
51     w = read(), n = read();
52     for (register int i = 1 ; i <= n ; i ++) a[i] = read();
53     
54     dfs(0, 0, n / 2); 
55     sort(t + 1, t + 1 + top);
56     dfs2(0, n/2+1, n);
57     cout << ans << endl;
58     return 0;
59 }

猜你喜欢

转载自www.cnblogs.com/zZh-Brim/p/9150069.html