//2013-3-26 Charlie
//百度之星题目——“负载均衡”
/*平衡负载
Du熊正在负责一个大型的项目,目前有K台服务器,有N个任务需要用这K台服务器来完成,所以要把这些任务分成K个部分来完成,在同上台服务器上执行的任务必须是连续的任务,每个任务有各自需要的执行时间。
例如N=5,K=2,每个任务需要时间分别为5,3,1,4,7分钟,那么我们可以分成(5)(3 1 4 7)两部分,这样第一台服务器所花时间就是5分钟,而第二台机器需要花15分钟,当然,所有任务完成的时间是按最迟完成的那台服务器的时间,即这样划分的话完成所有任务所需要的时间就是15分钟。而另外一种划分方法是(5 3 1)(4 7),这种划分方案完成所有任务的时间就是11分钟,也是最优的一种划分方案。
现在你的任务就是根据给定的N,K和每个任务要花费的时间,找出使完成所有任务时间最短的方案。
输入:
多组输入。
第一行输入N和K(1<=K<=N<=10000)。
第二行输入N个不大于1000的正整数,表示各个任要花费的时间。
N=K=0表示输入结束。
输出:
每行输出一个整数,对应对于每个数据(除了N=K=0不用输出)。
样例输入:
5 1
5 3 1 4 7
5 2
5 3 1 4 7
5 3
5 3 1 4 7
10 3
1 2 3 4 5 6 7 8 9 10
0 0
样例输出:
20
11
8
//百度之星题目——“负载均衡”
/*平衡负载
Du熊正在负责一个大型的项目,目前有K台服务器,有N个任务需要用这K台服务器来完成,所以要把这些任务分成K个部分来完成,在同上台服务器上执行的任务必须是连续的任务,每个任务有各自需要的执行时间。
例如N=5,K=2,每个任务需要时间分别为5,3,1,4,7分钟,那么我们可以分成(5)(3 1 4 7)两部分,这样第一台服务器所花时间就是5分钟,而第二台机器需要花15分钟,当然,所有任务完成的时间是按最迟完成的那台服务器的时间,即这样划分的话完成所有任务所需要的时间就是15分钟。而另外一种划分方法是(5 3 1)(4 7),这种划分方案完成所有任务的时间就是11分钟,也是最优的一种划分方案。
现在你的任务就是根据给定的N,K和每个任务要花费的时间,找出使完成所有任务时间最短的方案。
输入:
多组输入。
第一行输入N和K(1<=K<=N<=10000)。
第二行输入N个不大于1000的正整数,表示各个任要花费的时间。
N=K=0表示输入结束。
输出:
每行输出一个整数,对应对于每个数据(除了N=K=0不用输出)。
样例输入:
5 1
5 3 1 4 7
5 2
5 3 1 4 7
5 3
5 3 1 4 7
10 3
1 2 3 4 5 6 7 8 9 10
0 0
样例输出:
20
11
8
21*/
解法一:
#include <cstdlib>
#include <iostream>
using namespace std;
#define INFINITY 100000000
int time = INFINITY;
int count = 0;
int *a,*s;
int n,k;
//递归分配函数;
void allot(int n, int k);
//将数组a[]中,从count位置开始的前i个值的和存储到s[_k-1];
void save2s(int _k, int i, int count);
//求数组s[]中k个数的最大值;
int max_s();
int main(){
cin>>n>>k;
while(!(n==0&&k==0)){
a = (int*)malloc(n*sizeof(int));
s = (int*)malloc(k*sizeof(int));
for(int i=1;i<=n;i++)
cin>>a[i-1];
allot(n,k);
cout<<time<<endl;
free(a);
free(s);
time=INFINITY;
count=0;
cin>>n>>k;
}
return 0;
}
void allot(int n, int k){
//递归分配函数
if (k==1){
save2s(k,n,count);
int maxs = max_s();
if (maxs < time){
time = maxs;
}
return;
}
for(int i=1; i<=n-(k-1);i++){
save2s(k,i,count);
count+=i;
allot(n-i,k-1);
count-=i;
}
}
void save2s(int k, int i, int count){
int sum = 0;
for(int j = count;j<count+i;j++){
sum += a[j];
}
s[k-1] = sum;
}
int max_s(){
int max = 0;
for(int j=0;j<k;j++){
if (s[j]>max)
{
max = s[j];
}
}
return max;
}
解法一的另一种写法:
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
int n,k;
int *a,*divide;//a为输入数组,divide中每一个数代表一个机器所做任务的个数
int count;//组号0~k-1
// int time;//最终结果
void fun(int n,int k);
int result();
void print();
int main(){
ifstream cin("../input.txt");
if(cin.fail())cout<<"Input file error!"<<endl;
cin>>n>>k;
while(n!=0 && k!=0){
count=-1;
time=10000;
a=(int*)malloc(sizeof(int)*n);
divide=(int*)malloc(sizeof(int)*k);
for(int i=0;i<n;i++){
cin>>a[i];
}
fun(n,k);
cout<<time<<endl;
cin>>n>>k;
}
return 0;
}
void fun(int n,int k){
if(k==1 ){
divide[++count]=n;
int tmp=result();
if(tmp<time){
time=tmp;print();
}
count--;
return;
}
for(int i=1;i<=n-(k-1);i++){
divide[++count]=i;
fun(n-i,k-1);
count--;
}
}
//得到一次划分的运行时间
int result(){
int max=0;
int start=0;
int s;
for(int i=0;i<k;i++){
s=0;
for(int j=start;j<start+divide[i];j++){
s+=a[j];
}
if(s>max){
max=s;
}
start+=divide[i];
}
return max;
}
void print(){
for(int i=0;i<k;i++)
cout<<divide[i]<<',';
cout<<endl;
}
解法二:
//最优时间一定在均值和所有数和之间
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
int check(int x);
int n,k;
int *a;
int main(){
int sum;
int avg;
int maximum;
ifstream cin("../input.txt");
if(cin.fail())cout<<"Input file error!"<<endl;
cin>>n>>k;
while(n!=0 && k!=0){
sum=0;
maximum=10000;
a=(int*)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
cin>>a[i];
sum+=a[i];
}
avg=sum/k;//最后结果值必定在avg到sum之间
int s=0;
for(int i=avg;i<=sum;i++){
s=check(i);
if(s!=0 && s<maximum){
maximum=s;
}
}
cout<<maximum<<endl;
cin>>n>>k;
}
}
int check(int x){
bool flag=false;
int temp_max=0;
int temp=0;
int number=0;
for(int i=0;i<n;i++){
if(temp+a[i]<=x){
temp+=a[i];
if(temp==x)
flag=true;
if(i==n-1 && number==0)
temp_max=temp;
}else{
if(temp>temp_max){
temp_max=temp;
}
temp=0;
number++;
if(number>k){
flag=false;
break;
}
}
}
if(!flag)
return 0;
else
return temp_max;
}