c++背包模板

一.01背包

方法1:二维数组

(题目【模板】:洛谷P1048)

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int n, V;
int w[N], v[N];
int dp[N][N];
signed main()
{
    scanf("%d%d", &V, &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 = 1;j <= V;j++)
        {
            if (j < w[i]) dp[i][j] = dp[i-1][j];
            else dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);
        }
    }
    printf("%d", dp[n][V]);
    return 0;
}

方法二:一维数组滚动优化

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, V;
int w[N], v[N];
int dp[N];
signed main()
{
    scanf("%d%d", &V, &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 = V;j >= w[i];j--)
        {
            dp[j] = max(dp[j], dp[j-w[i]]+v[i]);
        }
    }
    printf("%d", dp[V]);
    return 0;
}

 

二.完全背包

其实就是把01背包的只有1件物品,改成了有无限件物品可以选择;

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, V;
int w[N], v[N];
int dp[N];
signed main()
{
    scanf("%d%d", &V, &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 <= V;j++)  //注意这里是正着循环      
        {
            if (j >= w[i]) dp[j] = max(dp[j], dp[j-w[i]]+v[i]);
        }
    }
    printf("%d", dp[V]);
    return 0;
}

三.多重背包

限制每个物品有s[i]个,求最大价值

代码(未优化):

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, V;
int w[N], v[N];
int dp[N], cnt = 1;
signed main()
{
    scanf("%d%d", &V, &n);
    for (int i = 1;i <= n;i++)
    {
        int vi, wi, si;        //价值,重量,数量 
        scanf("%d%d%d", &wi, &vi, &si);
        for (int j = 1;j <= si;j++)
        {
            v[cnt] = vi;
            w[cnt] = wi;
            cnt++;        //将多重背包拆成01背包 
        }
    }
    for (int i = 1;i <= cnt;i++)
    {
        for (int j = V;j >= w[i];j--)
        {
            dp[j] = max(dp[j], dp[j-w[i]]+v[i]);
        }
    }
    printf("%d", dp[V]);
    return 0;
}

 

优化:

int cnt = 1;
for (int i = 1;i <= n;i++)
    {
        int vi, wi, si;        //价值,重量,数量 
        scanf("%d%d%d", &wi, &vi, &si);
        int k = 1;
        while (k <= si)
        {
            v[cnt] = vi * k;
            w[cnt] = wi * k;
            si -= k;
            k *= 2;
            cnt++;
        }
        if (si > 0)
        {
            cnt++;
            v[cnt] = vi * si;
            w[cnt] = wi * si;
        }
    }

完结撒花(其实啥也没讲)

luogu:XiaoyuWan_

 

posted @ 2023-09-12 10:15  筱屿晚  阅读(136)  评论(0)    收藏  举报