最佳调度问题
来源:互联网 发布:李小冉 知乎 编辑:程序博客网 时间:2024/05/16 11:33
【问题描述】
假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。
【编程任务】
对任意给定的整数n和k,以及完成任务i需要的时间为ti,i=1~n。编程计算完成这n个任务的最佳调度。
【输入格式】
第一行有2 个正整数n和k。第2 行的n个正整数是完成n个任务需要的时间。
【输出格式】
将计算出的完成全部任务的最早时间输出。
【输入样例】
7 3
2 14 4 16 6 5 3
【输出样例】
17
这道题一开始没什么思路,贪心法不能得到最优解, 以为要把每个机器里的任务枚举出来。
其实可以这样想,每个机器里的任务数不确定,但每个任务可以放的机器数是确定的,所以可以搜索每个任务放到哪个机器里。
//machine-Milky#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,k,a[1005],c[1005],minnow=0x7fffffff;void dfs(int cur,int maxnow){ if(cur>n) {minnow=maxnow; return;} for(int i=1;i<=k;++i) { if(c[i]+a[cur]>=minnow) continue; c[i]+=a[cur]; dfs(cur+1,max(maxnow,c[i])); c[i]-=a[cur]; }}int main(){ freopen("machine.in","r",stdin); freopen("machine.out","w",stdout); scanf("%d%d\n",&n,&k); for(int i=1;i<=n;++i) scanf("%d",&a[i]); dfs(1,0); printf("%d\n",minnow); return 0; fclose(stdin); fclose(stdout);}
交上去有4个点TLE,loli说是因为minnow的初始值太大,限制不严格。
虽然贪心得出的解不是最优的,但也算是比较小的解,所以可以先贪心跑出一个minnow作搜索的限制。
//machine-Milky#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,k,a[1005],c[1005],minnow;void swapp(int &x,int &y){ x^=y; y^=x; x^=y;}int greedy(){ int g[1005]; for(int i=1;i<=n;++i) { g[k]+=a[i]; for(int j=k-1,t=k;j>=1;--j) { if(g[j]<g[t]) { swapp(g[j],g[t]); t=j; } else break; } } return g[1];}void dfs(int cur,int maxnow){ if(cur>n) {minnow=maxnow; return;} for(int i=1;i<=k;++i) { if(c[i]+a[cur]>=minnow) continue; c[i]+=a[cur]; dfs(cur+1,max(maxnow,c[i])); c[i]-=a[cur]; }}bool cmp(int x,int y) {return x>y;}int main(){ freopen("machine.in","r",stdin); freopen("machine.out","w",stdout); scanf("%d%d\n",&n,&k); for(int i=1;i<=n;++i) scanf("%d",&a[i]); sort(a+1,a+n+1,cmp); minnow=greedy(); dfs(1,0); printf("%d\n",minnow); return 0; fclose(stdin); fclose(stdout);}
虽然比刚才快了,但还是有两个点TLE。
loli的标准程序是把minnow初始成 sum/k+a[n] 即平均值加上一个最小值。但我举出一个反例,当n=k=2,输入 999 1 的时候就会出错。因为某个元素非常大,大于了平均值于最小值的和,就会直接输出minnow。
于是AH多次在loli的程序上加条件,在我多次举出反例推翻之后,终于得出一个似乎正确的方法。
(手动忽略此处)如果最大值大于平均值,minnow为最大值加最小值,否则为平均值加最小值。
但我又找出一个反例。然后我觉得他完全是在没有证明的情况下鬼扯。
当最大值大于平均值,minnow=最大值加最小值 的方法是对的,下面给出证明:我们假设取出最大的和最小的放到第一个容器里,剩下的物品分到 k-1 个容器里 它们的最大值永远不会超过第一个容器,因为 sum < n*maxn,所以 sum-maxn < (n-1) * maxn 实际上直接输出最大值就可以!
至于平均值大于最大值的情况。。我们继续探讨。
最后,有个正确的方法,跟第一个程序一样,minnow还是无穷大,只不过在搜索前加一个排序。
因为排序之后,能够更快地得到最优解,在此之后的搜索都会被剪枝,大大提升效率。此处代码省略。
- 最佳调度问题
- 最佳调度问题
- 【9506】最佳调度问题
- 最佳调度问题
- 最佳调度问题
- 最佳调度问题6_8
- 最佳调度问题 解题报告
- 最佳调度问题pascal程序
- 最佳调度问题的回溯算法
- 算法-回溯法解决最佳调度问题
- 搜索与回溯 最佳调度问题
- 回溯法——最佳调度问题
- 最佳调度问题的回溯算法(java实现)
- 《算法导论》实验三:最佳调度问题的回溯算法
- 多机最佳调度
- 11089 多机最佳调度
- kettle调度监控最佳实践
- 开源调度框架Quartz最佳实践
- AIDL的基本使用(一)
- Linux系统的"护花使者"-----守护进程
- View事件的传递
- css3元素向上移动
- R实战:【I/O】文本文件与因子转换
- 最佳调度问题
- VMware12安装Linux7系统进而安装Oracle12c中遇到的问题
- Java 写有n个人围成一圈,顺序排号,从第一个人开始报数(从1~3报数),凡报到3的人退出圈子,问最后留下的人原来排在第几号。
- 12-SpringBoot——Spring MVC基础-常用配置
- Mysql的高可用MHA实现
- web.xml与注解配置servlet使用介绍
- QThread的细节描述(Detailed Description)翻译
- eclipse自动提示设置以及问题:去除变量自动提示(图文详解)
- 7.16