01背包问题

本文详细解析了01背包问题的解决方法,包括简单的递归算法、带记忆化的搜索算法及动态规划算法,并通过示例代码说明每种方法的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

01背包问题:

有n个重量和价值分别为wi,vi的物品。从这些物品中挑出总重量不超过W的物品,求所有挑选方案中价值总和的最大值


记忆化搜索与动态规划:



先来看看单纯的递归是怎么写的

int func1(int i,int n,int lastWight)
{
    
    if(i==n) return 0;
    if(lastWight<W[i])
        reutrn func(i+1,n,lastWight);//放不下第i个物品
    else
         return max(func(i+1,n,lastWight),func(i+1,n,lastWight-W[i])+V[i]);                

                    //可要可不要时,取出两个中的最大值。
}




我们可以知道,在递归调用的过程中有的函数式被重复调用,而它的返回的结果是一样的。所以可以用数组来进行记忆。


int dp[MAX][MAX];
int func2(int i,int n,int lastWight)
{
    if(dp[i][lastWight]!=-1) return dp[i][lastWight];
    //如果这个函数之前已经被调用过了,就可以直接返回。
    int res;
    if(i==n)
    {
        res=0;
    }
    else if(lastWight<W[i])
    {
        res=func(i+1,n,lastWight);
    }
    else
    res=max(func(i+1,n,lastWight),func(i+1,n,lastWight-W[i])+V[i]);
    dp[i][lastWight]=res;//记下来。
    return res;
}


我们把要求结果范围内的所有情况都求出来直接用数组进行推导

动态规划:

int  func3()
{
    int i,j;
    for(j=0;j<W;j++)
    dp[0][j]=0;
    for(i=0;i<n;i++)
    {
        for(j=0;j<=W;j++) //w是背包能盛物品最大的重量。
        {
            if(j<W[i]) dp[i+1][j]=dp[i][j];//表示不能盛下。
            else dp[i+1][j]=max(dp[i][j],dp[i][j-W[i]]+V[i]); //表示把第i个物品选了。
        }
    }
    return dp[n][W];
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值