dp入门之01背包问题

...通过暴力手推得到的一点点感觉

  动态规划是相对于贪心算法的一种取得最优解的算法,通过对每一步的取舍判断从 0 推到所拥有的第 n 件物品,每次判断可以列写出状态转移方程,通过记忆化相对暴力地取得最优解,如果有 n 件物品,容量为 m 的背包,则时间复杂度为 O(n*m)

 

 

 

 

 

状态转移方程如下:

for(int i=1;i<=n;i++) 
        for(int j=0;j<=m0;j++)  
        {
            if(j>=w[i])
            {
                dp[i][j]=max(dp[i-1][j-w[i]]+v[i],dp[i-1][j]);
            }  
            else
            {
                dp[i][j]=dp[i-1][j];
            }              
        }

 

程序如下: 

#include "iostream"
#include "stdio.h"
using namespace std;
int w[105],v[105];
int dp[105][1005];
int main()
{
    int n,m;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&w[i],&v[i]);
    }
    for(int i=1;i<=n;i++) 
        for(int j=0;j<=m;j++)  
        {
            if(j>=w[i])
            {
                dp[i][j]=max(dp[i-1][j-w[i]]+v[i],dp[i-1][j]);
            }  
            else
            {
                dp[i][j]=dp[i-1][j];
            }              
        }
    printf("%d",dp[n][m]);
    return 0;
}

 考虑使用动态规划时,应先判断是否满足动态规划所需要的两个特性:

  1. 无后效性:简单来说就是过去与未来无关,只需要知道过去所取得最优解的结果,对于怎么取得的并不关心(比如本题中取得 f(3,5)=7时,只知道7是由 f ( 2 , 2 ) + v [ 3 ] = 3 + 4 = 7,并不关心过去的 f(2,2)时怎么得来的;
  2. 最优子结构性:即“大问题的最优解可以由小问题的最优解推出”(比如本题中得到的每一个 f ( i , j )都是判断是否舍去前一个 i 所带的信息

题目可以试做洛谷1048采药:https://www.luogu.org/problemnew/show/P1048

据说使用二维数组的空间复杂度太高,数据小大就会爆内存,因此便有一维数组的dp:

核心代码:

for(int i=1;i<=m;i++) 
  for(int j=t;j>=0;j--) 
    if(j>=w[i])
      dp[j]=max(dp[j-w[i]]+val[i], dp[j]);
    else dp[j]=dp[j];

正确性证明 :我还不会 :)谁来教教我orz

 

转载于:https://www.cnblogs.com/gogoflower/p/10639739.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值