面试题 背包问题的具体应用 打印出对应的序号

这是我看到的一个公司的面试题目,出题目的公司不知道是哪一个了。特意转载他的题目 解法是我给的 可能不是最好的

A公司供应各种档次的营养套餐,假设菜单上共有n项失误m1,m2,m3..mn,每种食物mi的营养价值为vi,价格为pi。套餐中每种失误之多出现一次,请完成以下两个小题:

(1)请为顾客设计算法。求解总价格不超过M的营养价值最大的套餐。

(2)具体列出来

    食物编号    营养价值    价格

      m1      100    25

      m2     225     50

     m3     150     40

     m4    150      30

     m5    80      10

列出总价格不超过100的营养价值最大的套餐对应的食物编号,以及对应的最大营养价值。

 

 

这是一个典型的动态规划的问题:

可以使用填表发:

申请一个  5*100的数组

相当于二维的数组,横坐标表示价格,纵坐标表示食品种类数目,a[i][j]表示当物品的种类为i的时候,总价值最大为j的时刻的营养价值

有以下的递推公式

若:j<w[i] v[i][j]=v[i-1][j];

否则: j>=w[i]. v[i][j]=max{v[i-1][j],v[i-1][j-w[i]]+vi[i]};

我们使用一个二维数组来表示搜索的规则:

以下为整个程序的代码:

#define N 5
#define W 12
int w[] = {-1, 2,5,4, 3,1};//物体的价值数组 2 5 3   (1 2 4)
int vi[] = {-1, 10,22,12,15,8};//营养数组  10 22 15
int v[N+1][W+1]; //v[i][j]表示物体的中i个物体的营养等于钱j的时候包含的最大营养价值  
int T[N+1][W+1];//搜索标志数组
enum{Init,kUp,kLeft,kUpLeft};
void init()
 {
     int  i, j;
     for (i = 0; i <= N; i++)
         for (j = 0; j <= W; j++)
		 {
			 T[i][j]=0;
             v[i][j] = -1;
		 }
     for (i = 0; i <= N; i++)
	 {
         v[i][0]=0;
		 T[i][0]=0;
	 }
     for (i=0; i <= W; i++)
	 {
		 v[0][i] = 0;
		 T[0][i]=0;
	 }
}
int MKFnapsack_MEMOIZE(int N1,int W1)
{
	for(int i=1;i<=N1;i++)
	{
		for(int j=1;j<=W1;j++)
		{
			if(j<w[i])
				v[i][j]=v[i-1][j];
			else
			{
				int value;
				int t1=v[i-1][j];
				int t2=v[i-1][j-w[i]]+vi[i];
				if(t1>=t2)
				{
					value=t1;
								}
				else
				{
					value=t2;
						T[i][j]=kUpLeft;

				}
				v[i][j]=value;
			}
		}
	}
	return v[N1][W1];
}
void print_v(int N1,int W1)
{
	for(int i=0;i<=N1;i++)
	{
		for(int j=0;j<=W1;j++)
		{
			cout<<v[i][j]<<" ";
		}
		cout<<endl;
	}
}
void print_T(int N1,int W1)
{
	for(int i=0;i<=N1;i++)
	{
		for(int j=0;j<=W1;j++)
		{
			cout<<T[i][j]<<" ";
		}
		cout<<endl;
	}
}
void Find_T_V(int i,int j)
{
	if(T[i][j]==0)
		Find_T_V(i-1,j);
	else
	{
		cout<<"编号:"<<i<<endl;
		int a=v[i][j]-vi[i];
		if(a==0)
			return;
		int k=0;
		while(a!=v[i][k])
		{
			k++;
		}
		Find_T_V(i,k);
	}
}
 int main()
 {
     init();
     printf("memoize most value is:%d\n", MKFnapsack_MEMOIZE(N, W));
	 print_v(N,W);
	 cout<<"..."<<endl;
	 print_T(N,W);
	 Find_T_V(N,W);
     return 0;
 }




 

下面是程序截图:

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值