第五章 动态规划 (一)(背包问题、)

一、问题类型(状态的表示和状态的转移)

背包问题、线性dp、区间dp、状态压缩dp、树形dp、计数、数位统计、状态压缩、记忆化搜索。

二、背包问题

(一)0 1背包(每件物品最多只用一次)

N个物品,V个背包。每个物品v表示体积,w表示权重。背包能装下的情况下,求最大的总价值。

0.1背包dp的思考方式:

1、如何表示状态、如何计算:   

如何表示状态:

2、状态就是一个满足条件的集合,集合是所有选法的集合(选哪些物品)。条件:只从前i个中选,总体积小于等于j。

3、状态的值f(i,j)就是集合的属性(max,min,数量)

4、答案是f(n,v);

如何进行状态计算:

1、状态计算是对集合的划分,对集合划分子集,以及如何经过划分后的子集进行计算得到结果

2、对集合f(i,j)进行划分:划分的依据就是子集是否包含i。一个是不包含i,一个是必须包含i

3、如何对划分的子集进行计算得到最后的结果:

4、对于必须含i的子集。如果要求最大值,可以先不去考虑i号,因为必须要选i号,所以先把i号物品刨除去,计算f(i-1,j-vi)+wi。

5、max(f(i-1 , j), f(i-1,j-vi)+wi)

01背包二维写法

#include<bits/stdc++.h>
using namespace std;
// 2  01背包 二维写法
const int N=1010;
int n,m;
int v[N],w[N];
int f[N][N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
    //全不选的话价值就是0
    for(int i=0;i<=m;i++)f[0][i]=0;

    //循环的方式扩大集合依次求解
    for(int i=1;i<=n;i++)
        for(int j=0;j<=m;j++)
        {
            //注意这样存在的一个错误性:vi比背包还大
            //f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
            f[i][j]=f[i-1][j];
            if(v[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值