背包问题的研究

背包问题

1. 01背包问题.

(1) 题意简述

[问题描述]

一个旅行者有一个最多能装 M M M公斤的背包,现在有 N N N件物品,他们的重量分别是 W 1 W_1 W1, W 2 W_2 W2, W 3 W_3 W3, . . . ... ..., W n W_n Wn,价值分别为 C 1 C_1 C1, C 2 C_2 C2, C 3 C_3 C3, . . . ... ..., C n C_n Cn,求旅行者能获得的最大价值.

[输入格式]

1 1 1行,两个整数, M , N M,N M,N

2 2 2 N + 1 N+1 N+1行,每行两个整数 W i , C i W_i,C_i Wi,Ci,表示每个物品的重量和价值.

(2) 解法

解法1:

F [ i ] [ v ] F[i][v] F[i][v]表示当前进行到第 i i i件物品,总重量小于等于 v v v的最大价值.故转移方程可以这样写: F [ i ] [ v ] = m a x ( f [ i − 1 ] [ v ] , f [ i − 1 ] [ v − w [ i ] ] + c [ i ] ) F[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]) F[i][v]=max(f[i1][v],f[i1][vw[i]]+c[i]) 最后输出 F [ n ] [ m ] F[n][m] F[n][m].

解法2:

我们会发现,每一次, i i i没有参与什么实质性的运算,所以,我们可以考虑删掉 i i i,只保留 v v v,其中, F [ v ] F[v] F[v]表示重量小于等于 v v v可获得的的最大价值.

所以,动态转移方程为: F [ v ] = m a x ( f [ v ] , f [ v − w [ i ] ] + c [ i ] ) F[v]=max(f[v],f[v-w[i]]+c[i]) F[v]=max(f[v],f[vw[i]]+c[i]),当且仅当 v > w [ i ] , 1 ≤ i ≤ n v>w[i],1≤i≤n v>w[i],1in时.

(3) 代码

解法1代码:

#include
using namespace std;
int m,n;
int w[31];
int c[31];
int f[31][201];
int main()
{
    cin>>m>>n;
    for(int i=1;i<=n;i++)
        cin>>w[i]>>c[i];
    for(int i=1;i<=n;i++)
    {
        for(int v=m;v>0;v--)
        {
            if(w[i]<=v)
            {
                f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]);
            }
            else
            {
                f[i][v]=f[i-1][v];
            }
        }
    }
    cout<<f[n][m]<<endl;
    return 0;
}

解法2代码:

#include
using namespace std;
int m,n;
int w[31];
int c[31];
int f[201];
int main()
{
    cin>>m>>n;
    for(int i=1;i<=n;i++)
        cin>>w[i]>>c[i];
    for(int i=1;i<=n;i++)
        for(int v=m;v>=w[i];v--)
            f[v]=max(f[v],f[v-w[i]]+c[i]);
    cout<<f[m]<<endl;
    return 0;
}

2. 完全背包问题

你可能感兴趣的:(c++,动态规划,背包问题,动态规划,算法)