【meet in the middle】的几个例题【BZOJ 4800】&【SPOJ ABCDEF】
2017-04-09 10:01
405 查看
【题目】SPOJABCDEF
传送门
【Solution】
可以将原式子转化成ab+c=d(e+f),用O(n3)来枚举,统计时自己手写一个二分查找(同map果断TLE)
还有,在枚举d时要保证d不为0,否则会WA,不知道为什么。
【Code】
【题目】BZOJ 4800
有n个物品,m块钱,给定每个物品的价格,求买物品的方案数。
【Solution】
朴素的折半搜索+剪枝
【Code】
传送门
【Solution】
可以将原式子转化成ab+c=d(e+f),用O(n3)来枚举,统计时自己手写一个二分查找(同map果断TLE)
还有,在枚举d时要保证d不为0,否则会WA,不知道为什么。
【Code】
#include<cstdio> #include<cstring> #include<algorithm> #define N 110 #define rep(i,x,y) for(int i = x;i <= y;i++) using namespace std; int s ,cnt,num[N*N*N]; int high(int x) { int L = 1,R = cnt,res = 0; while(L <= R) { int mid = (L+R)>>1; if(x >= num[mid]){L = mid+1;res = mid;} else R = mid - 1; } return res; } int low(int x) { int L = 1,R = cnt,res = 0; while(L <= R) { int mid = (L+R)>>1; if(x <= num[mid]){R = mid-1;res = mid;} else L = mid + 1; } return res; } int main() { int n,ans = 0; scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d",&s[i]); cnt = 0; rep(a,1,n) rep(b,1,n) rep(c,1,n) num[++cnt] = s[a]*s[b]+s[c]; sort(num+1,num+cnt+1); rep(d,1,n) rep(e,1,n) rep(f,1,n) if(s[d] != 0) { int x = s[d]*(s[e]+s[f]); int r = high(x),l = low(x); if(r >= l && r != 0 && l != 0) ans += r-l+1; } printf("%lld\n",ans); return 0; }
【题目】BZOJ 4800
有n个物品,m块钱,给定每个物品的价格,求买物品的方案数。
【Solution】
朴素的折半搜索+剪枝
【Code】
#include<cstdio> #include<cstring> #include<algorithm> #define N 45 typedef long long ll; using namespace std; ll a ,num1[1100000],num2[1100000],m; < 4000 span class="hljs-keyword">int deep,cnt1,cnt2,n; void dfs1(ll sum,int d) { if(d == deep+1) {num1[++cnt1] = sum;return;} if(sum+a[d] <= m) dfs1(sum+a[d],d+1); dfs1(sum,d+1); } void dfs2(ll sum,int d) { if(d == n+1) {num2[++cnt2] = sum;return;} if(sum+a[d] <= m) dfs2(sum+a[d],d+1); dfs2(sum,d+1); } int main() { scanf("%d%lld",&n,&m); for(int i = 1;i <= n;i++) scanf("%lld",&a[i]); if(n == 1) { if(a[1] <= m) puts("2"); else puts("1"); return 0; } deep = n/2; cnt1 = cnt2 = 0; dfs1(a[1],2); dfs1(0,2); sort(num1+1,num1+cnt1+1); deep++; dfs2(a[deep],deep+1); dfs2(0,deep+1); sort(num2+1,num2+cnt2+1); ll pos = cnt1,ans = 0; for(int i = 1;i <= cnt2;i++) { while(num2[i] > m - num1[pos] && pos > 0) pos--; ans += pos; } printf("%lld\n",ans); return 0; }
相关文章推荐
- 【BZOJ4800】[Ceoi2015]Ice Hockey World Championship Meet in the Middle
- BZOJ 4800([Ceoi2015]Ice Hockey World Championship-meet in the middle)
- BZOJ 4800: [Ceoi2015]Ice Hockey World Championship meet_in_the_middle
- bzoj 4800: [Ceoi2015]Ice Hockey World Championship meet in the middle
- [BZOJ4800][Ceoi2015][Meet In Middle]Ice Hockey World Championship
- bzoj1753 [Usaco2005 qua]Who's in the Middle
- POJ--2388 Who's in the Middle (续)
- poj2388——Who's in the Middle
- HDU 1157 Who's in the Middle
- Who's in the Middle
- POJ 2388 Who's in the Middle
- 北大OJ:2388:Who's in the Middle
- POJ--2388 Who's in the Middle
- POJ2388《Who's in the Middle》方法:排序
- POJ_2388 Who's in the Middle
- HDU 1157 Who's in the Middle
- poj 2388 Who's in the Middle
- POJ 2388 Who's in the Middle(堆排序)
- 杭电1157 Who's in the Middle
- [HDOJ 1157] Who's in the Middle (基础题)