004-3算法笔记【贪心】分析4-1、两个磁带存储

在这里插入图片描述

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;

const int maxn=100;
int A[maxn],B[maxn];//代表T1,T2两个磁带


//--------------------
//贪心算法
//--------------------
int suma = 0;
int sumb = 0; 
int posb = 0,posa=0;//A[]和B[]的指针

//先把第一个放在A上,第二个放在B上,后面的如果A集合里面的和大于B集合里面的和,就放在B中,否则就放在A中 
void minTime_greedy(vector<int>& a,int n) {
	memset(A,0,sizeof(A));
	memset(B,0,sizeof(B));
    //先把第一个放在A上,第二个放在B上
	int i = 0;
	A[posa] = a[i++];
	suma += A[posa++];
	B[posb] = a[i];
	sumb += B[posb++];

	for(i = 2; i < n; i++) {
		if(suma > sumb) {
			B[posb] = a[i];
			sumb += B[posb];
			posb++;
		}
		else {
			A[posa] = a[i];
			suma += A[posa];
			posa++;
		}
	}
}


//--------------------
//回溯法
//--------------------
int len[maxn];//程序段长度数组l[i]
int flag[maxn],bestx[maxn],C,bestp=0;   

void backtrack(int i,int cp,int n)   
{  
    if(i>n){//回溯的边界条件
        if(cp>bestp){//更新最优值
            bestp=cp;   
            for(i=0;i<=n;i++)    
                bestx[i]=flag[i];   
        }   
    }   
    else{
        for(int j=0;j<=1;j++){//j=1 取进A集合   
            flag[i]=j;//取舍标志  
            if(cp+j*len[i]<=C){      
                cp+=len[i]*j;   
                backtrack(i+1,cp,n);      
                cp-=len[i]*j;   
            }   
        }
	}   
}   
  
void distribution(int len[], int A[], int B[],int flag[],int n)  
{//将程序分配到A,B中   
    backtrack(1,0,n);   
    A[0] = B[0] = 0;//initialize the count of A and B  
    for(int i=1;i<=n;i++){   
        if(bestx[i] == 1) A[++A[0]] = len[i];   
        else  B[++B[0]] = len[i];  
    }   
}

void print(){
	cout<<"存放在磁带T1上的程序:"<<endl;
	cout<<"{";
	for(int i = 0; i < posa; i++) {
		cout<<A[i];
		if(i != posa-1){
			cout<<",";
		}
	}
	cout<<"}"<<endl;

	cout<<"存放在磁带T2上的程序:"<<endl;
	cout<<"{";
	for(int i = 0; i < posb; i++) {
		cout<<B[i];
		if(i != posb-1){
			cout<<",";
		}
	}
	cout<<"}"<<endl;
}

int main() {
	vector<int> a = {2, 14, 4, 16, 6, 5, 3};
    int n = a.size();

    cout<<"贪心:"<<endl;
	minTime_greedy(a,n);
    print();
	cout<<"最大检索时间:" ;
	cout<<max(suma,sumb)<<endl<<endl;


    memset(A,0,sizeof(A));
	memset(B,0,sizeof(B));

    
    cout<<"回溯:"<<endl;
    int sum = 0; //程序长度总和
    for (int i = 1; i <= n; i++)
    {
        len[i] = a[i - 1];
        sum += len[i];
    }
    C = sum / 2; //要使A,B集合长度和最大 值最小,最理想的情况是总和平分;也可以做capacity为sum/2的01背包
    distribution(len, A, B, flag, n);
    print();
	cout<<"最大检索时间:" ;
	cout<<max(suma,sumb)<<endl;

	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值