HUST 1354 Rubiks

来源:互联网 发布:mac双系统卸载windows 编辑:程序博客网 时间:2024/06/16 07:13

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 104 5 3 61 2 100 20012 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;}

0 0
原创粉丝点击