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 两组数据。

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <assert.h>
  7. #define IOS ios::sync_with_stdio(false)
  8. using namespace std;
  9. #define inf (0x3f3f3f3f)
  10. typedef long long int LL;
  11.  
  12. #include <iostream>
  13. #include <sstream>
  14. #include <vector>
  15. #include <set>
  16. #include <map>
  17. #include <queue>
  18. #include <string>
  19. #include <bitset>
  20. const int maxn = + ;
  21. int dp[ + ];
  22. int limit[maxn];
  23. int w[maxn][];
  24. int val[maxn];
  25. int togive;
  26. const int seed = ;
  27. typedef unsigned long long int ULL;
  28. ULL powseed[];
  29. int first[ + ];
  30. ULL Edge[ + ];
  31. int tonext[ + ];
  32. int id[ + ];
  33. int num;
  34. int toadd(ULL val) {
  35. int u = val % ;
  36. for (int i = first[u]; i; i = tonext[i]) {
  37. if (val == Edge[i]) return id[i];
  38. }
  39. ++num;
  40. tonext[num] = first[u];
  41. first[u] = num;
  42. Edge[num] = val;
  43. id[num] = ++togive;
  44. return togive;
  45. }
  46. int tohash(int a, int b, int c, int d, int e) {
  47. ULL val = a * powseed[] + b * powseed[] +
  48. c * powseed[] + d * powseed[] + e * powseed[];
  49. return toadd(val);
  50. }
  51. //适用于正负整数
  52. template <class T>
  53. inline bool fast_in(T &ret) {
  54. char c;
  55. int sgn;
  56. if(c = getchar(), c == EOF) return ; //EOF
  57. while(c != '-' && (c < '' || c > '')) c = getchar();
  58. sgn = (c == '-') ? - : ;
  59. ret = (c == '-') ? : (c - '');
  60. while(c = getchar(), c >= '' && c <= '') ret = ret * + (c - '');
  61. ret *= sgn;
  62. return ;
  63. }
  64. void work() {
  65. int n, m;
  66. // cin >> n >> m;
  67. // scanf("%d%d", &n, &m);
  68. fast_in(n);
  69. fast_in(m);
  70. for (int i = ; i <= m; ++i) {
  71. // cin >> limit[i];
  72. // scanf("%d", &limit[i]);
  73. fast_in(limit[i]);
  74. }
  75. for (int i = ; i <= n; ++i) {
  76. // cin >> val[i];
  77. // scanf("%d", &val[i]);
  78. fast_in(val[i]);
  79. for (int j = ; j <= m; ++j) {
  80. // cin >> w[i][j];
  81. // scanf("%d", &w[i][j]);
  82. fast_in(w[i][j]);
  83. }
  84. }
  85. // cout << tohash(1, 2, 3, 4, 5) << endl;
  86. // cout << tohash(1, 2, 4, 3, 5) << endl;
  87. // cout << tohash(1, 2, 3, 4, 5) << endl;
  88. int ans = ;
  89. for (int i = ; i <= n; ++i) {
  90. for (int a1 = limit[]; a1 >= w[i][]; --a1) {
  91. for (int a2 = limit[]; a2 >= w[i][]; --a2) {
  92. for (int a3 = limit[]; a3 >= w[i][]; --a3) {
  93. for (int a4 = limit[]; a4 >= w[i][]; --a4) {
  94. for (int a5 = limit[]; a5 >= w[i][]; --a5) {
  95. int now = tohash(a1, a2, a3, a4, a5);
  96. int pre = tohash(a1 - w[i][], a2 - w[i][], a3 - w[i][], a4 - w[i][], a5 - w[i][]);
  97. dp[now] = max(dp[now], dp[pre] + val[i]);
  98. ans = max(ans, dp[now]);
  99. }
  100. }
  101. }
  102. }
  103. }
  104. }
  105. printf("%d\n", ans);
  106. }
  107.  
  108. int main() {
  109. #ifdef local
  110. freopen("data.txt", "r", stdin);
  111. // freopen("data.txt", "w", stdout);
  112. #endif
  113. powseed[] = ;
  114. for (int i = ; i <= ; ++i) {
  115. powseed[i] = powseed[i - ] * seed;
  116. }
  117. work();
  118. return ;
  119. }

题解的那个hash我真看不懂。不是看不懂,是不理解。

其实他的意思类似于a * 1000000 + b * 100000 + c * 1000 + e * 100 * d * 10

这样类似的。但是明显这个值太大了。他就乘上了limit[i],这个我不能证明了,

好像又不会重复,数字又小。ORZ

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <assert.h>
  7. #define IOS ios::sync_with_stdio(false)
  8. using namespace std;
  9. #define inf (0x3f3f3f3f)
  10. typedef long long int LL;
  11.  
  12. #include <iostream>
  13. #include <sstream>
  14. #include <vector>
  15. #include <set>
  16. #include <map>
  17. #include <queue>
  18. #include <string>
  19. #include <bitset>
  20. const int maxn = + ;
  21. int dp[ + ];
  22. int limit[maxn];
  23. int w[maxn][];
  24. int val[maxn];
  25.  
  26. int tohash(int a, int b, int c, int d, int e) {
  27. return (a * (limit[] + ) * (limit[] + ) * (limit[] + ) * (limit[] + )
  28. + b * (limit[] + ) * (limit[] + ) * (limit[] + )
  29. + c * (limit[] + ) * (limit[] + ) + d * (limit[] + ) + e);
  30. }
  31. //适用于正负整数
  32. template <class T>
  33. inline bool fast_in(T &ret) {
  34. char c;
  35. int sgn;
  36. if(c = getchar(), c == EOF) return ; //EOF
  37. while(c != '-' && (c < '' || c > '')) c = getchar();
  38. sgn = (c == '-') ? - : ;
  39. ret = (c == '-') ? : (c - '');
  40. while(c = getchar(), c >= '' && c <= '') ret = ret * + (c - '');
  41. ret *= sgn;
  42. return ;
  43. }
  44. void work() {
  45. int n, m;
  46. // cin >> n >> m;
  47. // scanf("%d%d", &n, &m);
  48. fast_in(n);
  49. fast_in(m);
  50. for (int i = ; i <= m; ++i) {
  51. // cin >> limit[i];
  52. // scanf("%d", &limit[i]);
  53. fast_in(limit[i]);
  54. }
  55. for (int i = ; i <= n; ++i) {
  56. // cin >> val[i];
  57. // scanf("%d", &val[i]);
  58. fast_in(val[i]);
  59. for (int j = ; j <= m; ++j) {
  60. // cin >> w[i][j];
  61. // scanf("%d", &w[i][j]);
  62. fast_in(w[i][j]);
  63. }
  64. }
  65. // cout << tohash(1, 2, 3, 4, 5) << endl;
  66. // cout << tohash(1, 2, 4, 3, 5) << endl;
  67. // cout << tohash(1, 2, 3, 4, 5) << endl;
  68. int ans = ;
  69. for (int i = ; i <= n; ++i) {
  70. for (int a1 = limit[]; a1 >= w[i][]; --a1) {
  71. for (int a2 = limit[]; a2 >= w[i][]; --a2) {
  72. for (int a3 = limit[]; a3 >= w[i][]; --a3) {
  73. for (int a4 = limit[]; a4 >= w[i][]; --a4) {
  74. for (int a5 = limit[]; a5 >= w[i][]; --a5) {
  75. int now = tohash(a1, a2, a3, a4, a5);
  76. int pre = tohash(a1 - w[i][], a2 - w[i][], a3 - w[i][], a4 - w[i][], a5 - w[i][]);
  77. dp[now] = max(dp[now], dp[pre] + val[i]);
  78. ans = max(ans, dp[now]);
  79. }
  80. }
  81. }
  82. }
  83. }
  84. }
  85. printf("%d\n", ans);
  86. }
  87.  
  88. int main() {
  89. #ifdef local
  90. freopen("data.txt", "r", stdin);
  91. // freopen("data.txt", "w", stdout);
  92. #endif
  93. work();
  94. return ;
  95. }

感觉我的hash才是正确的打开方式

vijos P1426兴奋剂检查 多维费用背包问题的hash的更多相关文章

  1. VIJOS P1426兴奋剂检查[DP 状态哈希]

    背景 北京奥运会开幕了,这是中国人的骄傲和自豪,中国健儿在运动场上已经创造了一个又一个辉煌,super pig也不例外……………… 描述 虽然兴奋剂是奥运会及其他重要比赛的禁药,是禁止服用的.但是运动 ...

  2. HDU 2159 二维费用背包问题

    一个关于打怪升级的算法问题.. 题意:一个人在玩游戏老是要打怪升级,他愤怒了,现在,还差n经验升级,还有m的耐心度(为零就删游戏不玩了..),有m种怪,有一个最大的杀怪数s(杀超过m只也会删游戏的.. ...

  3. J. Bottles 二维费用背包问题

    http://codeforces.com/contest/730/problem/J 3 4    36    1 90   45   40 其实可以知道,选出多少个瓶子呢?是确定的,当然选一些大的 ...

  4. UESTC - 878 温泉旅店 二维费用背包问题

    http://acm.uestc.edu.cn/#/problem/show/878 设dp[i][j][k]表示在前i个数中,第一个得到的异或值是j,第二个人得到的异或值是k的方案数有多少种. 因为 ...

  5. vijos1426兴奋剂检查(多维费用的背包问题+状态压缩+hash)

    背景 北京奥运会开幕了,这是中国人的骄傲和自豪,中国健儿在运动场上已经创造了一个又一个辉煌,super pig也不例外……………… 描述 虽然兴奋剂是奥运会及其他重要比赛的禁药,是禁止服用的.但是运动 ...

  6. hdu_2159(二维费用背包)

    HDU_2159 二维费用背包问题 http://acm.hdu.edu.cn/showproblem.php?pid=2159 #include<cstdio> #include< ...

  7. 2159 ACM 杭电 杀怪 二维费用的背包+完全背包问题

    题意:已知经验值,保留的忍耐度,怪的种数和最多的杀怪数.求进入下一级的最优方案. 思路:用二维费用的背包+完全背包问题 (顺序循环)方法求解 什么是二维费用的背包问题? 问题: 二维费用的背包问题是指 ...

  8. 动态规划:HDU3496-Watch The Movie(二维费用的背包问题)

    Watch The Movie Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  9. 动态规划:HDU2159-FATE(二维费用的背包问题)

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

随机推荐

  1. VC++中的int main(int argc, char argv[])是什么意思

    这是C/C++的一重要函数,叫主函数.无论程序多复杂,代码中必须有这么一个函数,也只能有一个这样的函数:程序执行时就是从这个函数进入的.由于问得比较笼统,如果你想知道详细情况的话,发给你一个网友的求助 ...

  2. eclipse maven 插件的安装和配置

    maven3 安装: 安装 Maven 之前要求先确定你的 JDK 已经安装配置完毕.Maven是 Apache 下的一个项目.眼下最新版本号是 3.0.4.我用的也是这个. 首先去官网下载 Mave ...

  3. Num 36 : ZOJ 2100 [ 深度优先搜索算法 ] [ 回溯 ]

    该题是用回溯法来解决的题: 题目: Seeding Time Limit: 2 Seconds      Memory Limit: 65536 KB It is spring time and fa ...

  4. putty字体大小颜色、全屏/退出全屏快捷键 保存session设置[转]

    字体大小设置 Window->Appearance->Font settings->Change按钮设置(我的设置为16)字体为(Consolas) 字体颜色设置 Window-&g ...

  5. SQL Server 2012 从备份中还原数据库

    1.首先把原数据库备份,检查原数据库的日志文件是否太大,如果过于大应该先收缩数据库日志 2.把备份的数据库文件在目标SQL Server还原,点击数据库,选择“还原文件或文件组” 3.如果需要修改还原 ...

  6. VS2012变化的快捷键

    VS2012变化的快捷键: 注释::VS2010是(Ctrl+E,C),VS2012是(Ctrl+K, Ctrl+C),实际操作,按住Ctrl键不放,先按K键,再按C键.相当于Ctrl+K加 Ctrl ...

  7. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  8. Ubuntu Bochs boot.asm 测试

    /********************************************************************* * Ubuntu Bochs boot.asm 测试 * ...

  9. hdu4352(数位DP + LIS(nlogn))

    题目描述: 给定一个区间中,将区间的每一个数看成一个字符串,求这个区间内每个字符串的最大上升 子序列等于k的个数. 可以采用nlogn的LIS(用一个C数组记录长度为i的最大上升子序列的结尾最小值), ...

  10. iOS开发,#define的使用

    1.判断当前设备是不是iOS7以上版本 #define IOS_VERSION_7_OR_ABOVE (([[[UIDevice currentDevice] systemVersion] float ...