【二分\搜索\剪枝】软件下载
来源:互联网 发布:淘宝好做还是微店好做 编辑:程序博客网 时间:2024/06/03 16:50
3、软件下载
ICG大赛马上就要举行了,作为大赛的组委会兼参赛选手,信息组的成员们当然要做准备了,而其中十分重要的一项准备工作就是下载很多举办大赛必不可少的软件,已知现在机房有N台电脑,组委会列出了M个需要下载的软件及其大小Ai(即需要下载的时间),每个电脑同一时间只能下载一个软件,一个软件也只能由一个电脑下载,每个电脑下载速度相同且互不影响.因为有神器Cena的存在,每个软件只需由某一台电脑下载一次就能使整个机房的电脑普及该软件。现在ICG组委会想知道最快能在多长时间内下载完成。
输入格式
第1行:两个整数N、M,分别代表机房的电脑数及需要下载的软件数量。
第2行:M个整数,第i个整数表示Ai的值。
输出格式
一行一个整数,表示能下载完所有软件的最短时间。
输入样例:
2 3
1 2 3
输出样例
3
数据范围:
1<=n<=10
1<=m<=50
这道题比较好。因为考察了剪枝的技巧。
讨论二分的检验:
我一开始想的方法是N^M的方法,但是错误算成了M!/N!,所以导致我用了低效的方法。
正确的方法应该是M!的搜索,即先从大到小排序,依次把每一个软件分配给计算机。如果说分配不了了,那么,就分配到下一个计算机。否则可以选择分配给当前计算机,或者暂时不,转而判断下一个软件。
这样做仍然过不了。但是考虑而我们事先排了序,越到后面越小,假设我们以最优情况考虑,让每台电脑都以刚好以二分出的最短时间下载完,如果说这样都还不能下载完剩余的软件,则剪枝。这样就能秒过了。
关键是在于“越到后面时间长短越小”。。
#include <cstdio>#include <string>#include <cstring>#include <algorithm>#include <functional>using std::sort;#define min(a,b) ((a)<(b)?(a):(b))#define max(a,b) ((a)>(b)?(a):(b))long m,n;long mid;long a[60];long cnt[20];bool used[60];bool can(long u,long v,long left){if ((n-u+1)*mid-cnt[u] < left)return false;if (v == m)return true;for (long i=1;i<m+1;i++){if (!used[i]){if (cnt[u] + a[i] <= mid){used[i] = true;cnt[u] += a[i];if (can(u,v+1,left-a[i])) return true;cnt[u] -= a[i];used[i] = false;}else if (u < n){used[i] = true;cnt[u+1] += a[i];if (can(u+1,v+1,left-a[i])) return true;cnt[u+1] -= a[i];used[i] = false;}else return false;}}return false;}long getint(){long rs=0;bool sgn=1;char tmp;do tmp = getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp == '-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}int main(){freopen("soft.in","r",stdin);freopen("soft.out","w",stdout);n = getint();m = getint();long l = -0x3f3f3f3f;long r = 0;long sum = 0;for (long i=1;i<m+1;i++){a[i] = getint();r += a[i];l = max(l,a[i]);}sum = r;sort(a+1,a+1+m,std::greater<long>() );long ans = 0x3f3f3f3f;while (l <= r){mid = (l+r) >> 1;memset(used,0,sizeof used);memset(cnt,0,sizeof cnt);used[1] = true;cnt[1] = a[1];if (can(1,1,sum-a[1])){if (ans > mid)ans = mid;r = mid-1;}elsel = mid+1;}printf("%ld",ans);return 0;}
- 【二分\搜索\剪枝】软件下载
- 搜索算法--线性搜索、二分搜索、内插搜索、剪枝搜索
- BZOJ 1082 栅栏 (二分 剪枝搜索)
- hdoj 4004 The Frog's Games(二分+搜索+剪枝)
- 搜索剪枝
- 搜索剪枝
- 搜索 剪枝
- 搜索剪枝
- 搜索剪枝
- 剪枝搜索
- 【二分】软件下载解题报告
- hdu1455 Sticks(搜索+剪枝+剪枝+.....+剪枝)
- 【总结】搜索的剪枝二分预处理和离散化等优化
- Codeforces 366D Dima and Trap Graph(搜索剪枝/二分)
- codeforces 366D Dima and Trap Graph 题解(搜索+剪枝or二分+枚举)
- 搜索_剪枝
- alpha-beta剪枝搜索
- POJ - 1011 搜索剪枝
- 安装 Redis
- Android中的动画效果 .
- PHP中变量的作用域
- 公益慈善高职院校给大一新生发iPad引热议-iPad-教育扶贫-公益慈善
- AfxExtractSubString函数的使用
- 【二分\搜索\剪枝】软件下载
- 使用Gnu gprof进行Linux平台下的程序分析
- java读取jar里的文件
- 【递推】【动态规划】【数列】第二题 覆盖墙壁(wall.pas/c/cpp)
- Android开发系列:在Eclipse中导入Android项目方法
- Java多线程编程详解
- 彻底搞懂红黑树(三)
- python 、mysql、ajax_custom_select 深受困扰的问题
- 7.黑马程序员-数组