vijos P1426兴奋剂检查 多维费用背包问题的hash
2017-02-16 00:19
337 查看
https://vijos.org/p/1426
这是个好题,容易想到用dp[i][v1][v2][v3][v4][v5]表示在前i个物品中,各种东西的容量是那个的时候,能产生的最大价值。
时间不会TLE,但是会MLE.所以就需要把那5维状态进行hash
其实就是对这个排列进行一个hash。
newState: v1, v2, v3, v4, v5这个排列。
oldState: v1 - w[1], v2 - w[2], v3 - w[3], v4 - w[4], v5 - w[5]
这个排列。
然后要进行hash。我写了一个hash。TLE 两组数据。
View Code
感觉我的hash才是正确的打开方式
这是个好题,容易想到用dp[i][v1][v2][v3][v4][v5]表示在前i个物品中,各种东西的容量是那个的时候,能产生的最大价值。
时间不会TLE,但是会MLE.所以就需要把那5维状态进行hash
其实就是对这个排列进行一个hash。
newState: v1, v2, v3, v4, v5这个排列。
oldState: v1 - w[1], v2 - w[2], v3 - w[3], v4 - w[4], v5 - w[5]
这个排列。
然后要进行hash。我写了一个hash。TLE 两组数据。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 200 + 20; int dp[5000000 + 20]; int limit[maxn]; int w[maxn][10]; int val[maxn]; int tohash(int a, int b, int c, int d, int e) { return (a * (limit[2] + 1) * (limit[3] + 1) * (limit[4] + 1) * (limit[5] + 1) + b * (limit[3] + 1) * (limit[4] + 1) * (limit[5] + 1) + c * (limit[4] + 1) * (limit[5] + 1) + d * (limit[5] + 1) + e); } //适用于正负整数 template <class T> inline bool fast_in(T &ret) { char c; int sgn; if(c = getchar(), c == EOF) return 0; //EOF while(c != '-' && (c < '0' || c > '9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } void work() { int n, m; // cin >> n >> m; // scanf("%d%d", &n, &m); fast_in(n); fast_in(m); for (int i = 1; i <= m; ++i) { // cin >> limit[i]; // scanf("%d", &limit[i]); fast_in(limit[i]); } for (int i = 1; i <= n; ++i) { // cin >> val[i]; // scanf("%d", &val[i]); fast_in(val[i]); for (int j = 1; j <= m; ++j) { // cin >> w[i][j]; // scanf("%d", &w[i][j]); fast_in(w[i][j]); } } // cout << tohash(1, 2, 3, 4, 5) << endl; // cout << tohash(1, 2, 4, 3, 5) << endl; // cout << tohash(1, 2, 3, 4, 5) << endl; int ans = 0; for (int i = 1; i <= n; ++i) { for (int a1 = limit[1]; a1 >= w[i][1]; --a1) { for (int a2 = limit[2]; a2 >= w[i][2]; --a2) { for (int a3 = limit[3]; a3 >= w[i][3]; --a3) { for (int a4 = limit[4]; a4 >= w[i][4]; --a4) { for (int a5 = limit[5]; a5 >= w[i][5]; --a5) { int now = tohash(a1, a2, a3, a4, a5); int pre = tohash(a1 - w[i][1], a2 - w[i][2], a3 - w[i][3], a4 - w[i][4], a5 - w[i][5]); dp[now] = max(dp[now], dp[pre] + val[i]); ans = max(ans, dp[now]); } } } } } } printf("%d\n", ans); } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }
View Code
感觉我的hash才是正确的打开方式
相关文章推荐
- vijos1426兴奋剂检查(多维费用的背包问题+状态压缩+hash)
- vijos1426兴奋剂检查(多维费用的背包问题+状态压缩+hash)
- TOJ 3596. Watch The Movie【基础的二维费用背包问题】
- P05: 二维费用的背包问题
- hdu 4501 动态规划 + 费用背包问题
- 二维费用的背包问题
- hdu - 2660 Accepted Necklace (二维费用的背包问题)
- 背包问题总结第六讲——二维费用的背包问题
- 杭电2159-二维费用的背包问题
- HDU 2159 二维费用背包问题
- P05:二维费用的背包问题
- 第七讲 有依赖的背包问题 vijos P1313金明的预算方案
- P05: 二维费用的背包问题
- 【背包九讲】P05: 二维费用的背包问题
- HDU 2159 FATE 动态规划二维费用的背包问题
- HDU 2159 二维费用背包问题
- P05: 二维费用的背包问题
- hdu 2159 二维费用背包问题
- P05: 二维费用的背包问题
- 杭电 2159 FATE(二维费用背包问题)