HUST 1354 Rubiks

Description

Isun is a genius. Not only he is an expert in algorithm, but also he plays damn-good in many funny games. Besides, he can recover a Rubik in 16 seconds or even less. The man is very crazy about Rubiks, and he has bought a lot of Rubiks. As we know, there are so many kinds of Rubiks in the world. Isun wants to buy the most valuable ones with his limited money. There are N kinds of Rubiks in all. Each of them has a  price Pi(1<=i<=N) RMB and a  value Vi(1<=i<=N). Isun will pay no more than M (RMB) in total. In addition, there are some Rubik families like “甲X” or “封X”. And a kind of Rubik belongs to one family at most. If Isun buys a group of them, the value of them as a family will increase. Can you get the largest value of the Rubiks that Isun can get with M (RMB). (Isun just buy one Rubik each kind at most)

Input

The input contains several test cases and is ended by EOF. Each test case begins with two integers: N (1<=N<=1000) and M (1<=M<=10000). The second line contains N integers representing the prices of the Rubiks. (1<=Pi<=10000) The third line contains N integers representing the value of the Rubiks. (1<=Vi<=10000) Then a line contains an integer G(0<=G<=15) representing the number of the Rubik families. Next G lines each with a start of an integer Si(1<=Si<=N) representing the number of Rubiks in the ith family. The following Si integers represent Rubik’s id (which start from 1 to N). And an integer Yi at the end means the value increased if you buy them all.(1<=Yi<=10000)

Output

There should be one line per test case containing the largest value.

Sample Input

4 10
4 5 3 6
1 2 100 200
1
2 1 2 330

Sample Output

333

Hint

Isun will buy Rubik 1 and Rubik 2, which make up family 1 and get 330 value increased. So they value 333 in all which is the largest value Isun can get with 10 RMB.

分组的dp,对于没有组的先直接01背包,然后同一组内的做一次01背包,把整个组当做一个物品做一次01背包,合起来就好了

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<functional>
using namespace std;
typedef unsigned long long ull;
typedef long long LL;
const int INF = 0x7FFFFFFF;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
int T, n, m, w[maxn], v[maxn], G[maxn], gg, f[maxn], vis[maxn], dp[maxn];
vector<int> g[maxn];

int main()
{
	while (scanf("%d%d", &n, &m) != EOF)
	{
		for (int i = 0; i < n; i++) scanf("%d", &w[i]);
		for (int i = 0; i < n; i++) scanf("%d", &v[i]);
		for (int i = 0; i <= m; i++) f[i] = 0;
		for (int i = 0; i < n; i++) vis[i] = 0;
		scanf("%d", &gg);
		for (int i = 0; i < gg; i++)
		{
			g[i].clear();
			int x, y; scanf("%d", &x);
			while (x--){ scanf("%d", &y), g[i].push_back(y - 1); vis[y - 1] = 1; }
			scanf("%d", &G[i]);
		}
		for (int i = 0; i < n; i++)
		{
			if (vis[i]) continue;
			for (int j = m; j >= w[i]; j--)
			{
				f[j] = max(f[j], f[j - w[i]] + v[i]);
			}
		}
		for (int i = 0; i < gg; i++)
		{
			for (int j = 0; j <= m; j++) dp[j] = f[j];
			int x = 0, y = G[i];
			for (int j = 0; j < g[i].size(); j++)
			{
				x += w[g[i][j]];	y += v[g[i][j]];
				for (int k = m; k >= w[g[i][j]]; k--)
				{
					dp[k] = max(dp[k], dp[k - w[g[i][j]]] + v[g[i][j]]);
				}
			}
			for (int k = m; k >= x; k--) f[k] = max(f[k], f[k - x] + y);
			for (int k = 0; k <= m; k++) f[k] = max(f[k], dp[k]);
		}
		printf("%d\n", f[m]);
	}
	return 0;
}

你可能感兴趣的:(HUST 1354 Rubiks)