算法--递归(5)

0/1 背包问题

背包可容 纳物品的最大质量为m,现有n件物品,质量分别为m1, m2,。。。, mn,mi均为正整数,要从n件物品中挑选若干件,使放入背包的质量之和正好为m

放入背包中,则为0,没有放入背包中,则为1

理解:
对于第n个物品mn来说,
if mn = m
return true
if mn > m
if n > 1
Knap(m, n-1)
else
return false
if mn < m
if n>1
if (Knap(m-mn, n-1))
return true
else
Knap(m, n-1)
else
return false

#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;

//求n个元素的全排列
//自然数拆分

// 0/1 背包问题
/*
 * 理解:
对于第n个物品mn来说,
if mn = m
return true
if mn > m
	if n > 1
		Knap(m, n-1)
	else
		return false
if mn <  m
	if n>1
		if (Knap(m-mn, n-1))
			return true
		else
			Knap(m, n-1)
	else
		return false
 */

int a[100];
int b[100];

bool Knap(int m, int n)
{
    int temp = a[n];
    if(temp == m)
    {
        b[n] = 1;
        return true;
    }
    if(temp > m)
    {
        if(n <= 1)
            return false;
        return Knap(m, n-1);
    }
    if (temp < m)
    {
        if(n <= 1)
          return false;
        if(Knap(m-temp, n-1))
        {
            b[n] = 1;
            return true;
        }
        else
        {
            b[n] = 0;
            return Knap(m, n-1);
        }
    }
}




int main(void)
{
    int m = 20;
    a[1]=3;a[2]=5;a[3]=8;a[4]=9;a[5]=10;
    Knap(m, 5);
    for (int i = 1; i <= 5; ++i)
    {
        cout << b[i] << endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值