HUST 1354 Rubiks
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HUST 1354 Rubiks相关的知识,希望对你有一定的参考价值。
背包。注释写详细了。
本想这样写:每个组内各自做背包,然后组间做背包,但是由于这题M=10000,时间复杂度太大。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<iostream> #include<algorithm> #include<bitset> #include<functional> using namespace std; const int maxn = 10000 + 10; int n, m, g; vector<int>G[20]; int cost[1000 + 10]; int val[1000 + 10]; int y[20]; bool flag[1000 + 10]; int dp1[10000 + 10]; int dp2[10000 + 10]; void init() { memset(flag, 0, sizeof flag); for (int i = 1; i <= g; i++) G[i].clear(); } int main() { while (~scanf("%d%d", &n, &m)){ for (int i = 1; i <= n; i++) scanf("%d", &cost[i]); for (int i = 1; i <= n; i++) scanf("%d", &val[i]); scanf("%d", &g); init(); for (int i = 1; i <= g; i++) { int f; scanf("%d", &f); for (int j = 1; j <= f; j++) { int id; scanf("%d", &id); G[i].push_back(id); flag[id] = 1; } scanf("%d", &y[i]); } memset(dp1, 0, sizeof dp1); //没有组的归为一组 for (int i = 1; i <= n; i++) { if (flag[i]) continue; for (int j = m; j >= cost[i]; j--) dp1[j] = max(dp1[j], dp1[j - cost[i]] + val[i]); } for (int k = 1; k <= g; k++) { //此时dp2数组存储了之前的所有组合最优解 for (int i = 1; i <= m; i++) dp2[i] = dp1[i]; //接下来假设不买完这个组合内的魔方,这样DP的话事实上也存在买完的组合,但会被之后的dp2更新,所以不存在问题 for (int s = 0; s < G[k].size(); s++) { for (int j = m; j >= cost[G[k][s]]; j--) { dp1[j] = max(dp1[j], dp1[j - cost[G[k][s]]] + val[G[k][s]]); } } //假设买完,用dp2更新 int sum_cost = 0, sum_val = y[k]; for (int s = 0; s < G[k].size(); s++) { sum_cost = sum_cost + cost[G[k][s]]; sum_val = sum_val + val[G[k][s]]; } for (int j = m; j >= sum_cost; j--) { dp2[j] = max(dp2[j], dp2[j - sum_cost] + sum_val); } //然后dp1和dp2存下最大值 for (int i = 0; i <= m; i++) dp1[i] = max(dp1[i], dp2[i]); } printf("%d\n", dp1[m]); } return 0; }
以上是关于HUST 1354 Rubiks的主要内容,如果未能解决你的问题,请参考以下文章