一、最初的思路来源——n个任务,m个服务器,求最短时间
(1)算法含义
本质上这个算法是在m条一维度线上对n个任务量大小的分配,尽可能平均,以至于结果最小。
最优性:在diaodu()中,会先在第一个服务器上一条路跑到黑,然后刷新mintime,再跑回前面的任务分配步骤,在每一个任务的分配上不断分支。以此来满足最优性。
优化性: if(x[i]+a[j]<mintime),用这个条件会剪掉明显不符合的分支。
(2)代码
#include<bits/stdc++.h> using namespace std; int n,m;//n为任务数量,m为服务器数量 int a[10001];//当前任务的w值 int x[1001];//当前服务器的总时间 int mintime=100000;//最短时间 void diaodu(int j,int s) { if(j>n+1)//当任务都填入数组时开始判断时间最小值是否被刷新 if(s<mintime) mintime=s; if(s>=mintime) return; for(int i=1;i<=m;i++)//第i个数组意味着给第i个服务器赋值 { if(x[i]+a[j]<mintime)//这里是为了减支,在保证最优解的前提下减小计算的难度 { x[i]+=a[j]; diaodu(j+1,max(s,x[i]));//递归,考虑到了所有的分支保证了一定是最优解 x[i]-=a[j]; } } } int main() { cout<<"输入n与m,n表示任务数,m表示服务器数量"<<endl; cin>>n>>m; cout<<"输入n个数据,代表任务的时间"<<endl; for(int i=1;i<=n;i++) cin>>a[i]; diaodu(1,0);//从第一个服务器,该服务器时间和为0开始 cout<<mintime<<endl;//输出最短时间 return 0; }
(3)演示案例
(4)缺点
因为是不断刷新最短时间来保证的最优性,所有也只输出了最短时间,对分配这个问题,没能直接输出方案有点本末倒置。
二、输出最短时间的同时,也输出方案。
(1)算法含义
- 在1的基础上用t,u两个二维数组来存放每个服务器上的任务编号
(2)代码
> #include<bits/stdc++.h>
> using namespace std;
>
> int n,m;
> int a[10001];//当前任务的w值
> int x[1001];//当前服务器的v总0
> int t[1001][10001];//放当前服务器的编号
> int u[1001][10001];
> int mintime=100000;
> int fenlie=1;
>
> void diaodu(int j,int s)
> {
> if(j>n+1)
> if(s<mintime)
> {
> minVzong=s;
> memcpy(u,t,1001*10001*sizeof(int));
> }
> if(s>=mintime)
> return;
>
> for(int i=1;i<=m;i++)
> {
> if(x[i]+a[j]<mintime)
> {
> x[i]+=a[j];
> t[i][j]=j;
> diaodu(j+1,max(s,x[i]));
> t[i][j]=0;
> x[i]-=a[j];
> }
> }
> }
>
> int main()
> {
> cout<<"输入n与m,n表示任务数,m表示服务器数量"<<endl;
> cin>>n>>m;
> cout<<"输入n个数据,代表任务的w"<<endl;
> for(int i=1;i<=n;i++)
> cin>>a[i];
> diaodu(1,0);
> for(int i=1;i<=m;i++)
> {
> printf("服务器%d:",i);
> for(int j=1;j<=n;j++)
> if(u[i][j]!=0)
> printf("%d ",u[i][j]);
> printf("\n");
> }
> cout<<"最短时间:"<<mintime<<endl;
> return 0;
> }
(3)演示示例
(4)缺点
时间复杂度上,一言难尽。
经过尝试,20 3还能1s多跑完。20 4则半分钟。如果输入100 1000…
我觉得太湖之光也救不了我。