P1757 通天之分组背包(分组背包裸题)

题目背景
直达通天路·小A历险记第二篇

题目描述
自01背包问世之后,小A对此深感兴趣。一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。

输入格式
两个数m,n,表示一共有n件物品,总重量为m

接下来n行,每行3个数ai,bi,ci,表示物品的重量,利用价值,所属组数

输出格式
一个数,最大的利用价值

输入输出样例
输入 #1 复制
45 3
10 10 1
10 5 1
50 400 2
输出 #1 复制
10
说明/提示
1<=m<=1000 1<=n<=1000 组数t<=100

思路: 将状态定义改为组数而不是个数就可以了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>using namespace std;const int maxn = 1e3 + 7;
int dp[maxn],w[maxn],v[maxn],c[maxn][105];int main()
{int n,m;scanf("%d%d",&m,&n);int num = 0;for(int i = 1;i <= n;i++){int t;scanf("%d%d%d",&w[i],&v[i],&t);c[t][++c[t][0]] = i;num = max(num,t);}for(int i = 1;i <= num;i++){for(int j = m;j >= 0;j--){for(int k = 1;k <= c[i][0] ;k++){if(j - w[c[i][k]] >= 0)dp[j] = max(dp[j],dp[j - w[c[i][k]]] + v[c[i][k]]);}}}printf("%d\n",dp[m]);return 0;
}