通天之分组背包

传送门:https://www.luogu.org/problemnew/show/P1757

通天之分组背包,送你上青天。

设f[k][v]表示前k组物品花费费用为v时能获得的最大值

则有f[k][v] = max(f[k-1][v],f[k-1][v-c[i]]+w[i]) 其中i属于第k组

根据一维01背包可知此背包同样可以降维

设一数组d[k][i]表示第k组依次存了哪几号物品

当i=0时,d[k][0]表示第k组物品有几件

代码如下,循环层次不可改变

#include<cstdio>
#include<algorithm>
using namespace std;
int m,n,a[1001],b[1001],c,d[1001][1001],sum,f[1001];
int main(){
    scanf("%d%d",&m,&n);
    for(int i = 1;i <= n;i++){
        scanf("%d%d%d",&a[i],&b[i],&c);
        d[c][++d[c][0]] = i;
        sum = max(sum,c);
    }
    for(int k = 1;k <= sum;k++)
        for(int j = m;j >= 0;j--)
            for(int i = 1;i <= d[k][0];i++)
                if(j-a[d[k][i]] >= 0)
                    f[j] = max(f[j],f[j-a[d[k][i]]] + b[d[k][i]]);
    printf("%d",f[m]);
    return 0;            
}
原文地址:https://www.cnblogs.com/peppa/p/9885707.html