bzoj1082 跨栏 二分&搜索
2015-12-06 12:40
351 查看
果然搜索的姿势很重要啊。首先二分答案x,那么剪下来的一定是最小的x个,然后枚举每一个从哪块上切下来就行了。有以下优化:
1.将两个数组分别排序。那么所需要的木板一定是从大到小枚举,同时枚举每一个所需要的木板时,按照提供的木板的大小从小到大枚举能不能切去,这样容易回溯。
2.对于一块提供的木板,如果其长度小于需要的最小的木板,那么剩下来的部分一定浪费了。记一个变量waste表示浪费的部分,那么如果waste+所需要的木板总长度>提供的木板总长度,直接回溯。
3.对于相邻的两块所需要的木板,如果长度相等,那么后一块直接从前一块上次放的那一块开始枚举,避免重复运算。
4.类似于小木棒,如果某一块所需要的木板刚好和已有的一块目前剩下的相等,如果这样也得不到答案,直接回溯。实测效果不大,没有写。
5.二分不一定要从0~m,可以缩小范围。实测效果好像不是很大,懒得删了。
大概就这些了,AC代码如下:
by lych
2015.12.6
1.将两个数组分别排序。那么所需要的木板一定是从大到小枚举,同时枚举每一个所需要的木板时,按照提供的木板的大小从小到大枚举能不能切去,这样容易回溯。
2.对于一块提供的木板,如果其长度小于需要的最小的木板,那么剩下来的部分一定浪费了。记一个变量waste表示浪费的部分,那么如果waste+所需要的木板总长度>提供的木板总长度,直接回溯。
3.对于相邻的两块所需要的木板,如果长度相等,那么后一块直接从前一块上次放的那一块开始枚举,避免重复运算。
4.类似于小木棒,如果某一块所需要的木板刚好和已有的一块目前剩下的相等,如果这样也得不到答案,直接回溯。实测效果不大,没有写。
5.二分不一定要从0~m,可以缩小范围。实测效果好像不是很大,懒得删了。
大概就这些了,AC代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 2005 using namespace std; int n,m,p,tot,wst,sum ,a ,b ; bool dfs(int k,int last){ if (!k) return 1; int i; if (wst+sum[p]>tot) return 0; for (i=last; i<=n; i++) if (a[i]>=b[k]){ a[i]-=b[k]; if (a[i]<b[1]) wst+=a[i]; if (b[k]==b[k-1]){ if (dfs(k-1,i)){ if (a[i]<b[1]) wst-=a[i]; a[i]+=b[k]; return 1; } } else if (dfs(k-1,1)){ if (a[i]<b[1]) wst-=a[i]; a[i]+=b[k]; return 1; } if (a[i]<b[1]) wst-=a[i]; a[i]+=b[k]; } return 0; } bool ok(int x){ p=x; wst=0; return dfs(p,1); } int main(){ scanf("%d",&n); int i; for (i=1; i<=n; i++){ scanf("%d",&a[i]); tot+=a[i]; } scanf("%d",&m); int l=0,r=m; for (i=1; i<=m; i++) scanf("%d",&b[i]); sort(a+1,a+n+1); sort(b+1,b+m+1); for (i=1; i<=m; i++){ sum[i]=sum[i-1]+b[i]; if (sum[i]>tot) r=min(r,i-1); if (a[i]>b[i]) l++; } while (l+1<r){ int mid=(l+r)>>1; if (ok(mid)) l=mid; else r=mid-1; } if (l==r) printf("%d\n",l); else if (ok(r)) printf("%d\n",r); else printf("%d\n",l); return 0; }
by lych
2015.12.6
相关文章推荐
- Android Studio 无法关联到 svn
- Light oj--1148
- 九度OJ 1357:疯狂地Jobdu序列 (数字特性)
- 黑马程序员——OC学习——Protocol和代理设计模式
- 解决MySQL服务器禁止远程连接的问题
- 1103. Integer Factorization (30)
- 1102. Invert a Binary Tree (25)
- 九度OJ 1357:疯狂地Jobdu序列 (数字特性)
- poj 2516 Minimum Cost KM算法
- HDOJ 1003 Max Sum参考程序
- LightOJ 1348 Aladdin and the Return Journey(树链剖分+线段树)
- 1100. Mars Numbers (20)
- iBatis iterate标签
- 1099. Build A Binary Search Tree (30)
- 1098. Insertion or Heap Sort (25)
- org.apache.hadoop.hbase.ClockOutOfSyncException: org.apache.hadoop.hbase.ClockOutOfSyncException: Se
- UIDeviceOrientation
- 1097. Deduplication on a Linked List (25)
- [LeetCode]Implement Trie (Prefix Tree)
- 【思考一】Android程序员想做手机游戏开发