回溯法解装载问题

来源:互联网 发布:java游戏地图编辑器 编辑:程序博客网 时间:2024/05/18 21:08

递归解法

#include<iostream>
using namespace std;
int bestw=0;
int cw=0;
int num=3;
int r=46;
int bestx[3];
void load(int *w,int c,int n,int *x)
{
 if(n>=num)
 {
  if(cw>bestw)
  {
   for(int i=0;i<n;i++)
   { bestx[i]=x[i];
    bestw=cw;
   }
  }
  return ;
 } 
 r-=w[n];
 if(cw+w[n]<=c)
 { 
  cw+=w[n];
  x[n]=1;
  load(w,c,n+1,x);
  cw-=w[n];  
 }
 if(cw+r>bestw)
 {
  x[n]=0;
  load(w,c,n+1,x); 
 }
 r+=w[n];
}
int main(void)
{int w[]={ 16,15,15};
int x[]={0};
load(w,30,0,x);
cout<<bestw;
for(int i=0;i<num;i++) 
cout<<bestx[i];
return 0;
}

 

非递归解法

#include <iostream>
using namespace std;

int MaxLoading( int w[ ],int c, int n, int bestx[ ] )
{ //迭代回溯
    int i = 0; //当前层
    // x[1: i -1]为当前路径
    int *x = new int[ n ];
    int bestw = 0;
 int  cw = 0;
 int r = 0;
 for( int j = 0; j <n; j++)
  r += w[j];
 
 while( true ){
  while( i< n && cw + w[i] <= c) {
   // 进入左子树
            r -= w[ i ];
            cw += w[i];
            x[i] = 1;
            i++;
  }
  if( i == n) { //到达叶结点
   for( int j = 0; j < n; j++)
    bestx[j] = x[j];
   bestw = cw;}
  else {  //进入右子树       
            r -= w[i];
            x[i] = 0;
            i++;}    
  while( cw + r <= bestw  ){
   // 剪枝回溯
   i --;    
   while ( i >= 0 && !x[ i ] ) {
    //从右子树返回
    r += w[i];
    i --;
   }
   if( i == -1) { delete [] x;
   return bestw; }
   // 进入右子树
   x[ i ] = 0;
   cw -= w[i];
   i ++;
  }
 }
}    


int main()
{
 int w[]={16,15,15};
 int bestx[3];
 cout<<MaxLoading( w,30, 3, bestx);
 for(int i=0;i<3;i++)cout<<bestx[i];
 return 0;
}

原创粉丝点击