dp背包问题(一)

        动态规划向来的都是算法问题的难点,在经过一段时间的学习和练习,总结一下一些背包问题的原型。

        01背包

        01背包可以说是所有背包问题的基础,大致的题意是你有一个容量为v的背包,然后又n种物品,每种物品都有其价值和体积,求出你能拿到最大的物品价值。dp[i][j]表示在拿前面i种物品中,在体积为j的背包,你所能拿到物品的最大价值。这里我们就不难得出状态转移方程,如果这件第i个物品不拿,dp[i][j]=dp[i-1][j],如果第i件物品要拿,dp[i][j]=dp[i-1][j-v[i]]+w[i];

        下面是一道例题

输入文件的第一行有两个整数 T和 M,用一个空格隔开,T代表总共能够用来采药的时间,M 代表山洞里的草药的数目。

接下来的 M行每行包括两个在 1 到 100 之间(包括 1 和 1001)的整数,分别表示采摘某株草药的时间和这株草药的价值

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1001;
int p[N],T[N];
int dp[N][N];
dp[i][j]=dp[i-1][j],dp[i][j]=dp[i-1][j-v[i]]+w[i];
int main(){
    int t,m;
    cin>>t>>m;
    for(int i=1;i<=m;i++){
        cin>>T[i]>>p[i];
        }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=t;j++){
            dp[i][j]=dp[i-1][j];
            if(j>=T[i]){
                dp[i][j]=max(dp[i][j],dp[i-1][j-T[i]]+p[i]);
            }
        }
    }
    cout<<dp[m][t]<<"\n";
    return 0;
}

为了方便理解就没有用滚动数组优化空间。如果变成一维的j应该从t开始枚举。

完全背包

完全背包问题就有了不同,完全背包是给你一个体积为v的背包,n种物品,但是每种物品都有无限个可以无限拿,每种物品的价值又有所不同,求出你所能拿到的最大价值。同样的状态表示:dp[i][j];表示前i种物品中所选物品容量不超过j的最大价值。

dp[i][j]=max(dp[i-1][j],dp[i-1][j-1*v]+1*w,dp[i-1][j-2*v]+2*w,……)
dp[i][j-v]=max(         dp[i-1][j-v],dp[i-1][j-2*v]+w,dp[i-1][j-3v]+2w……)

通过上面的推导,我们不难发现dp[i][j]=max(dp[i-1][j],dp[i-1][j-v]+w),由此得出状太转移的方程。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e3+3;
int w[N],y[N];
int dp[N][N];
int main(){
    int n,v;
    cin>>n>>v;
    for(int i=1;i<=n;i++)cin>>y[i]>>w[i];
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=v;j++){
            dp[i][j]=dp[i-1][j];
            if(j>=y[i]){
                dp[i][j]=max(dp[i-1][j],dp[i][j-y[i]]+w[i]);//注意
            }
        }
    }
    cout<<dp[n][v]<<"\n";
    return 0;
}

这里如果要优化成一维数组直接改就行,v直接从1开始枚举,这也是所有背包问题能优化到一维的一个唯一不用将j逆过来的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值