[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 }