算法分析题——n个程序分配于2个磁盘

题目描述

把长度为 l 1 , l 2 . . . l n l_1,l_2...l_n l1,l2...ln n n n个程序放在磁带 T 1 , T 2 T_1,T_2 T1,T2上,并且希望按照使用最大检索时间取得最小值的方式存储,即如果存放在 T 1 , T 2 T_1,T_2 T1,T2上的程序集合分别为 A A A B B B,则希望所选择的 A A A B B B使得 m a x { ∑ i ∈ A l i , ∑ i ∈ B l i } max\{\sum_{i\in{A}} l_i ,\sum_{i\in{B}} l_i \} max{iAli,iBli}取得最小值。
可以采用动态规划法或者回溯法,这里采用回溯法
这里给出2个测试样例
样例1:
输入

8
1 3 6 7 5 4 8 4

输出

7 8 4
1 3 6 5 4

样例2:
输入

7
5 8 9 4 1 2 5

输出

9 1 2 5
5 8 4
#include <iostream>   
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define FOR(i,s,e) for (int i=(s); i<(e); i++)
#define FOE(i,s,e) for (int i=(s); i<=(e); i++)
#define FOD(i,s,e) for (int i=(s); i>=(e); i--)   
const int maxn=1e6;
int n;//程序的数目 
int len[maxn];//程序段长度数组l[i] 
int f[maxn],bestx[maxn],C,bestp=0;   
int seta[maxn],setb[maxn]; //存放分配程序的A,B集合   
int sum=0;//程序长度总和 
  
void backtrack(int i,int cp) //回溯法   
{  
    if(i>n){//回溯的边界条件   
        if(cp>bestp){//更新最优值
            bestp=cp;   
            for(i=0;i<=n;i++)    
                bestx[i]=f[i];   
        }   
    }   
    else{
    	FOE(j,0,1){//j=1 取进A集合   
            f[i]=j;//取舍标志  
            if(cp+j*len[i]<=C){      
                cp+=len[i]*j;   
                backtrack(i+1,cp);      
                cp-=len[i]*j;   
            }   
        }
	}   
}   
  
void distribution(int len[], int seta[], int setb[],int f[])  
{//将程序分配到A,B中   
    backtrack(1,0);   
    seta[0] = setb[0] = 0;//initialize the count of A and B  
    FOE(i,1,n){   
        if(bestx[i] == 1) seta[++seta[0]] = len[i];   
        else  setb[++setb[0]] = len[i];  
    }   
}   

int main()   
{
    cin>>n;             
    //len[0] = n;    
    for(int i=1; i<=n; i++)   
    {  
        cin>>len[i];   
        sum+=len[i];   
    }   
    C = sum/2;//要使A,B集合长度和最大值最小,最理想的情况是总和平分     
    distribution(len,seta,setb,f);   
    //输出A,B磁盘存放程序情况 
    FOE(i,1,seta[0]){   
        cout<<seta[i];
		if(i==seta[0]) cout<<endl; 
		else cout<<" ";  
    }   
    FOE(i,1,setb[0]){   
        cout<<setb[i]; 
		if(i==setb[0]) cout<<endl; 
		else cout<<" ";  
    }    
    return 0;   
}
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值