动态规划之01背包

本文详细介绍了01背包问题的基本概念与解决方法,包括二维与一维的实现方式,并通过实例问题“hdu2564饭卡”展示了具体的代码实现过程。

给你n个物品,还有一个容量为v的容器,随后在给你n个物品的重量c和价值w

F[i][j]表示把前i个物品放在容量为j的背包的最大价值

然后根据第i件物品是否要放来决策

    

F[i-1][j]表示前i-1个物品放在容量为j的背包中的最大价值

F[i-1][j-C[i]]+W[i]表示若是要放第i件物品 那么前i-1个物品所要用的背包容量为j-C[i]

然后取两者的最大值即可

二维的做法:

for(int i = 1; i <= n; i++)
{
    for(int j = 0; j <= v; j++)
    {
        F[i][j] = (i==1?0:F{i-1}[j]);
        if(j >= C[i])
        F[i][j] = max(F[i][j],F[i-1][j-C[i]]+W[i]);
    }
}

一维的方法

 for(int i = 1; i <= n; i++)
        {
            for(int j = v; j >= C[i]; j--)
            {
                F[j] = max(F[j],F[j-C[i]]+W[i]);
            }
        }

  当然一维要比二维的空间复杂度小

一些浅显的认识,欢迎提意见


那么接下来就看看实际问题吧 

hdu 2564 饭卡

点击打开题目链接


如果输入的m大于5  那么要用5元去买最贵的菜  然后在剩余的菜 进行01背包的算法就可以了

AC代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
int pr[3000],dp[3000];
int max(int x,int y)
{
    if(x < y)
        return y;
    else
        return x;
}
int main()
{
    int max1,n,m;
    while(cin >> n,n)
    {
        memset(dp,0,sizeof(dp));
        memset(pr,0,sizeof(pr));
        for(int i = 1; i <= n; i++)
            scanf("%d",&pr[i]);
        sort(pr + 1, pr + 1 + n);
        max1 = pr[n];
        scanf("%d",&m);
        if(m<5)
        {
            printf("%d\n",m);
            continue;
        }
        m-=5;     ///保留5元  买最贵的
        for(int i = 1; i < n; i++)
        {
            for(int j = m; j >= pr[i]; j--)
            {
                dp[j] = max(dp[j],dp[j-pr[i]]+pr[i]);
            }
        }
        printf("%d\n",m+5-max1-dp[m]);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值