分组背包如何保证每组只取一个

分组背包如何保证每组只取一个

必须从状态方程出发,已知分组背包问题的状态表示是

dp[i][j]: 考虑前i组,体积不超过j的情况下,能获得的最大值
当我们在更新第i组时,i本身没有变,只是将第i组所有元素遍历一遍,尝试更新本组的最大值,不会发生重复选择的情况,

给出一个实例,假定先选择了A,此时
dp[i][j] = dp[i - 1][j - v[a]] + w[a];
之后又发现B更好,就变成了
dp[i][j] = dp[i - 1][j - v[b]] + w[b];
此时dp[i][j]就会被b更新,且这次的更新不依赖之前选A产生的结果,只跟前i-1组的状态dp[i-1]相关,选择A产生的结果会被覆盖,因此保证了每组只选一个
#include<iostream>
using namespace std;

const int N = 110;
int v[N][N], w[N][N], s[N];
int dp[N][N];

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    {
        cin >> s[i];
        for(int j = 0; j < s[i]; j++)
            cin >> v[i][j] >> w[i][j];
    }
    
    for(int i = 1; i <= n; i++)
        for(int j = 0; j <= m; j++)
            {
                dp[i][j] = dp[i - 1][j];
                for(int k = 0; k < s[i]; k++)
                    if(j >= v[i][k]) dp[i][j] = max(dp[i][j], dp[i-1][j-v[i][k]]+w[i][k]);
            }
            
    cout << dp[n][m];
}
posted @ 2022-09-13 20:31  INnoVation-V2  阅读(101)  评论(0编辑  收藏  举报