题意:

给你 n 张卡片,总共可以消耗的法力值,求最多可以造成多少伤害, 卡片分为2种,一种是魔法卡,使用后可以使所有的连环卡的费用全部减1,另一种是连环卡,因魔法卡的使用可以使其费用减1,问最终最多可以造成多少的伤害

思路分析 :

比赛的时候大脑短路了,基本不愿意去想东西了,导致题目没有出来,这个题就是一个 01背包,但是增加了一个限制条件,所以我们多增加一维表示到当前位置,所使用的魔法卡的数量,但是呢,还有一个很关键的地方,就是我们要先对卡片经行一个排序的预处理,这样在搞 dp的时候,才不会对后续有任何的影响,排序的时候,优先使用魔法卡,然后两者都是的卡,剩下的卡就随意了。

代码示例:(未测试)

  1. #define ll long long
  2. const int maxn = 1e6+5;
  3. const int mod = 1e9+7;
  4. const double eps = 1e-9;
  5. const double pi = acos(-1.0);
  6. const int inf = 0x3f3f3f3f;
  7.  
  8. int n, w;
  9.  
  10. struct node
  11. {
  12. int w, x, p1, p2;
  13.  
  14. }pre[505];
  15. int dp[505][505][505];
  16. int cnt = 0;
  17.  
  18. bool cmp1(node a, node b){
  19. if (a.p1 == b.p1) return a.p2 < b.p2;
  20. return a.p1 > b.p1;
  21. }
  22.  
  23. bool cmp2(node a, node b){
  24. if (a.w == b.w) return a.x > b.x;
  25. return a.w < b.w;
  26. }
  27.  
  28. void fun(){
  29.  
  30. for(int i = 1; i <= n; i++){
  31. for(int j = 1; j <= w; j++){
  32. for(int k = 0; k <= min(i, cnt); k++){ // 使用魔法卡
  33. if (pre[i].p1 && !pre[i].p2) { // 1 0
  34. if (j >= pre[i].w && k)
  35. dp[i][j][k] = max(dp[i-1][j][k], dp[i-1][j-pre[i].w][k-1]+pre[i].x);
  36. else dp[i][j][k] = dp[i-1][j][k];
  37. }
  38. else if (pre[i].p1 && pre[i].p2){ // 1 1
  39. int cost = max(pre[i].w-k+1, 0);
  40. //if (i == 2 && j == 2) printf("cost = %d\n", cost);
  41. if (j >= cost && k){
  42. dp[i][j][k] = max(dp[i-1][j][k], dp[i-1][j-cost][k-1]+pre[i].x);
  43. }
  44. else dp[i][j][k] = dp[i-1][j][k];
  45. }
  46. else if (!pre[i].p1 && pre[i].p2){ // 0 1
  47. int cost = max(pre[i].w-k, 0);
  48. if (j >= cost && k){
  49. dp[i][j][k] = max(dp[i-1][j][k], dp[i-1][j-cost][k]+pre[i].x);
  50. }
  51. else dp[i][j][k] = dp[i-1][j][k];
  52. }
  53. else { // 0 0
  54. if (j >= pre[i].w){
  55. dp[i][j][k] = max(dp[i-1][j][k], dp[i-1][j-pre[i].w][k]+pre[i].x);
  56. }
  57. else dp[i][j][k] = dp[i-1][j][k];
  58. }
  59. //printf("+++%d %d %d = %d \n",i, j, k, dp[i][j][k]);
  60. }
  61. }
  62. }
  63. }
  64.  
  65. void init(){
  66. int pos1 = -1, pos2 = -1;
  67.  
  68. for(int i = 1; i <= n; i++){
  69. if (pre[i].p1 && !pre[i].p2) {
  70. pos1 = i;
  71. break;
  72. }
  73. }
  74. for(int i = n; i >= 1; i--){
  75. if (pre[i].p1 && !pre[i].p2) {
  76. pos2 = i;
  77. break;
  78. }
  79. }
  80. if (pos1 != -1) sort(pre+pos1, pre+pos2+1, cmp2);
  81.  
  82. pos1 = pos2 = -1;
  83. for(int i = 1; i <= n; i++){
  84. if (pre[i].p1 && pre[i].p2) {
  85. pos1 = i;
  86. break;
  87. }
  88. }
  89. for(int i = n; i >= 1; i--){
  90. if (pre[i].p1 && pre[i].p2) {
  91. pos2 = i;
  92. break;
  93. }
  94. }
  95. if (pos1 != -1) sort(pre+pos1, pre+pos2+1, cmp2);
  96.  
  97. pos1 = pos2 = -1;
  98. for(int i = 1; i <= n; i++){
  99. if (!pre[i].p1 && !pre[i].p2) {
  100. pos1 = i;
  101. break;
  102. }
  103. }
  104. for(int i = n; i >= 1; i--){
  105. if (!pre[i].p1 && !pre[i].p2) {
  106. pos2 = i;
  107. break;
  108. }
  109. }
  110. if (pos1 != -1) sort(pre+pos1, pre+pos2+1, cmp2);
  111.  
  112. pos1 = pos2 = -1;
  113. for(int i = 1; i <= n; i++){
  114. if (!pre[i].p1 && pre[i].p2) {
  115. pos1 = i;
  116. break;
  117. }
  118. }
  119. for(int i = n; i >= 1; i--){
  120. if (!pre[i].p1 && pre[i].p2) {
  121. pos2 = i;
  122. break;
  123. }
  124. }
  125. if (pos1 != -1) sort(pre+pos1, pre+pos2+1, cmp2);
  126. }
  127.  
  128. int main() {
  129. //freopen("in.txt", "r", stdin);
  130. //freopen("out.txt", "w", stdout);
  131.  
  132. cin >> n >> w;
  133. for(int i = 1; i <= n; i++){
  134. scanf("%d%d%d%d", &pre[i].w, &pre[i].x, &pre[i].p1, &pre[i].p2);
  135. if (pre[i].p1 == 1) cnt++;
  136. }
  137. sort(pre+1, pre+1+n, cmp1);
  138. init();
  139. for(int i = 1; i <= n; i++){
  140. printf("%d%d%d%d\n", pre[i].w, pre[i].x, pre[i].p1, pre[i].p2);
  141. }
  142. memset(dp, 0x8f, sizeof(dp));
  143. for(int j = 0; j <= w; j++) {
  144. dp[0][j][0] = 0;
  145. }
  146. fun();
  147. int ans = 0;
  148. for(int i = 0; i <= cnt; i++) ans = max(ans, dp[n][w][i]);
  149. printf("%d\n", ans);
  150. return 0;
  151. }
  152. /*
  153. 4 3
  154. 1 3 0 1
  155. 1 0 0 0
  156. 3 3 1 1
  157. 3 4 1 0
  158.  
  159. 3 3
  160. 3 3 1 1
  161. 2 3 1 1
  162. 1 3 1 1
  163.  
  164. 3 4
  165. 3 10 1 1
  166. 30 400 1 1
  167. 4 200 1 1
  168.  
  169. 5 5
  170. 6 50 1 1
  171. 3 30 0 1
  172. 3 3 1 0
  173. 3 200 0 0
  174. 3 6 1 0
  175.  
  176. 6 4
  177. 1 3 1 0
  178. 2 5 0 0
  179. 1 2 0 1
  180. 2 2 1 1
  181. 3 4 0 1
  182. 1 1 1 0
  183. */

dp - 3维背包(东四省)的更多相关文章

  1. 二维背包(钟神想要的)(不是DP)

    [问题描述] 背包是个好东西,希望我也有.给你一个二维的背包,它的体积是? × ?.现在你有一些大小为1× 2和1×3的物品,每个物品有自己的价值.你希望往背包里面装一些物品,使得它们的价值和最大,问 ...

  2. HDU 2159 FATE (DP 二维费用背包)

    题目链接 题意 : 中文题不详述. 思路 : 二维背包,dp[i][h]表示当前忍耐值为i的情况下,杀了h个怪得到的最大经验值,状态转移方程: dp[i][h] = max(dp[i][h],dp[i ...

  3. dp 二维乃至多维背包

    洛谷P1855 榨取kkksc03 分析:套路是很明显的01背包,但是这时受约束的变量有两个了,这种情况下就该用多维背包了 分析方法一样的,用dp[i][j][k]表示从前i个愿望中挑选总时间和总金钱 ...

  4. dp之二维背包poj2576

    题意:有一群sb要拔河,把这群sb分为两拨,两拨sb数只差不能大于1,输出这两拨人的体重,小的在前面...... 思路:把总人数除2,总重量除2,之后你会发现就是个简单的二维背包,有两个限制..... ...

  5. (第三场) A PACM Team 【dp,五维背包】

    链接:https://www.nowcoder.com/acm/contest/141/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...

  6. hdu 4501 小明系列故事——买年货_二维背包

    题目:你可以有v1元,v2代金券,v3个物品免单,现在有n个商品,商品能用纸币或者代金券购买,当然你可以买v3个商品免费.问怎么最大能买多少价值 题意: 思路二维背包,dp[v1][v2][v3]=M ...

  7. poj1742 多维背包

    普通的多维背包做不了,需要优化一下 但是没有学优化..别的方法也是可以做的 省去一个 表示阶段的 i 维度,dp[j]表示面值为j的钱是否被凑出来了,used[j]表示第i种硬币在凑面值为j的时候被用 ...

  8. HDU 2159 FATE (二维背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159 解题报告:这题实际上是一个二维的背包问题,也可以由01背包扩展而来,01背包用一维数组,可想而知 ...

  9. rqnoj-329-刘翔!加油!-二维背包

    注意排除干扰项. 因为价值不会相等,所以价值的多少与本题没有任何关系,. 所以价值为干扰项,所以不用考虑. 二维背包,简单求解. #include<stdio.h> #include< ...

随机推荐

  1. Spring Boot Thymeleaf 使用详解

    在上篇文章Spring Boot (二):Web 综合开发中简单介绍了一下 Thymeleaf,这篇文章将更加全面详细的介绍 Thymeleaf 的使用.Thymeleaf 是新一代的模板引擎,在 S ...

  2. python模块之random模块

    random模块 随机模块,用于处理随机问题. import random # 随机整数 print(random.randint(0, 9)) # 0到9之间随机一个整数 print(random. ...

  3. Vue打包文件放在服务器,浏览器存在缓存问题的解决

    在入口文件index.html添加 <meta http-equiv="pragram" content="no-cache"> <meta ...

  4. JavaMail转发邮件

    最近要做一个邮件转发功能,看了好多blog,都是接受邮件,再解析邮件内容,再组装成新的邮件发出! 我按照这个不够,不错!邮件发出去了.但是好麻烦啊,接受邮件是个Message,发送邮件也是个Messa ...

  5. Qt3升至Qt4需要注意的几件事项浅谈

    Qt3升至Qt4需要注意的几件事项浅谈 公司以前的项目是用Qt3写的,随着时间的推移慢慢显示出Qt3有多方面的限制,因此先公司决定用Qt4来改写这个项目,并为软件添加新功能,在此背景先编写此文章. 先 ...

  6. CITRIX ADC配置SSL卸载

    如上图,将ssl的加密解密放在前端的负载均衡设备上,客户端到VPX的访问都是加密的,VPX到后端的服务器都是http的 Step1:上传证书到VPX,如下图: Step2:创建SSL的虚拟服务器并且绑 ...

  7. 深入谷歌和甲骨文旷日持久的版权战争,趣味科普当前最火的编程语言JAVA的前世今生

    这篇文章是我在B站上投稿的一个科普java的视频文案,内容如标题,感兴趣的码农朋友可以移步观看https://www.bilibili.com/video/av81171108/ 在过去短短几十年间, ...

  8. DOCKER学习_003:Docker的存储

    一 简介 docker提供数据卷来实现数据共享与持久化,而数据卷的挂载有两种方式: 挂载主机目录(Bind mounts) 数据卷容器(Data Volumes) 数据卷是一个可供容器使用的特殊目录, ...

  9. GNE: 4行代码实现新闻类网站通用爬虫

    GNE(GeneralNewsExtractor)是一个通用新闻网站正文抽取模块,输入一篇新闻网页的 HTML, 输出正文内容.标题.作者.发布时间.正文中的图片地址和正文所在的标签源代码.GNE在提 ...

  10. 【题解】P5446 [THUPC2018]绿绿和串串(manacher)

    [题解]P5446 [THUPC2018]绿绿和串串(manacher) 考虑对于一个串进行\(f\)操作,就是让他变成一个以最后一个节点为回文中心的回文串. 那么对于某个位置\(p\),假如它是一个 ...