2018年东北地区赛S - Problem I. Spell Boost HDU - 6508

2018年东北地区赛S - Problem I. Spell Boost HDU - 6508

题目地址:https://vjudge.net/problem/HDU-6508

思路:
给一些卡,分为四种卡。
1.白卡(没效果)
2.魔法,作用卡(会对作用卡的费用减少,也会被魔法卡作用)
3.作用卡(会被魔法卡作用使其费用减少)
4.魔法卡(会对作用卡的费用减少)
有一个想法:如果我们得到最大的攻击力,其中会用到魔法卡和作用卡或者两者效果都有的卡的话,魔法卡其实是越早用越好,而作用卡越晚用晚用越好,因为作用卡会被魔法卡影响,使其费用减少,而且费用少的卡需要先使用,才能尝试更多的可能,如果一张卡是10w,一张卡是1w,为了尝试更多可能,先让费用少的先尝试,让费用多的之后对dp[N][N]进行比较。
那么,dp[N][N],第一个维度为费用值,第二个维度为用了几张魔法卡,维护的是最大攻击力。
然后就是一个01背包问题,当然为了实现我们的想法,需要对结构体进行某些特定的排序。


  1 #include<iostream>
  2 #include<algorithm>
  3 using namespace std;
  4 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
  5 #define per(i,j,k) for(int i = (j); i >= (k); i--)
  6
  7 const int N = 510;
  8 int dp[N][N];
  9
 10 struct node{
 11     int w, x;
 12     int is_m, is_s;
 13
 14     bool friend operator < (node a, node b){
 15         if (a.is_m != b.is_m) return a.is_m > b.is_m;//魔法卡先返回
 16         else if (a.is_s != b.is_s) return a.is_s < b.is_s;//作用卡越晚用越好
 17
 18         return a.w < b.w;//先用费用小的,使其dp可以得到全部可能
 19     }
 20 };
 21
 22 node arr[N];
 23
 24 void init(int x){
 25 //    rep(i, 0, x)rep(j, 0, x) dp[i][j] = 0;
 26     memset(dp, 0, sizeof(dp));
 27 }
 28
 29 int main(){
 30
 31     ios::sync_with_stdio(false);
 32     cin.tie(0);
 33
 34     int n, W;
 35     while (cin >> n >> W){
 36
 37         int m_num = 0;
 38
 39         rep(i, 1, n){
 40             cin >> arr[i].w >> arr[i].x >> arr[i].is_m >> arr[i].is_s;
 41             if (arr[i].is_m) ++m_num;//统计魔法卡数量
 42         }
 43
 44         init(n);
 45
 46         sort(arr + 1, arr + 1 + n);
 47
 48         bool is_s = false;//判断是不是作用卡
 49         //从大到小遍历,可以不影响之前的状态
 50         rep(i, 1, n){
 51             if (arr[i].is_m){
 52
 53                 per(k, i, 1){//魔法卡从多到少
 54                     per(j, W, 0){//费用从多到少
 55
 56                         int tmp_w = 0;
 57                         if (arr[i].is_s){//有被作用效果
 58                             is_s = true;
 59                             tmp_w = max(0, arr[i].w - (k - 1));//触发魔法卡效果
 60                         }
 61                         //对于k张魔法卡,之前只有k-1张魔法卡,假如一张魔法卡去更新dp,所以被作用时
 62                         //应该是魔法卡数量-1的费用减少
 63                         if (is_s && tmp_w <= j){//是作用卡,费用足够
 64                             dp[j][k] = max(dp[j][k],dp[j - tmp_w][k - 1] + arr[i].x);
 65                         }
 66                         else if (!is_s && arr[i].w <= j){//不是作用卡,费用足够
 67                             dp[j][k] = max(dp[j][k], dp[j - arr[i].w][k - 1] + arr[i].x);
 68                         }
 69                     }
 70                 }
 71             }
 72             else {
 73                 //进入该部分时,全部的魔法卡使用情况已经存入dp,之后的都不是魔法卡
 74                 per(k, m_num, 0){//m_num是魔法卡总数量,可能有不用魔法卡才能的到最大攻击的情况
 75                     per(j, W, 0){
 76
 77                         int tmp_w = 0;
 78                         if (arr[i].is_s){
 79                             is_s = true;
 80                             tmp_w = max(0, arr[i].w - k);
 81                         }
 82                         //对于k张魔法卡,被作用卡卡费用减少k
 83                         if (is_s && tmp_w <= j){
 84                             dp[j][k] = max(dp[j][k], dp[j - tmp_w][k] + arr[i].x);
 85                         }
 86                         else if (!is_s && arr[i].w <= j){
 87                             dp[j][k] = max(dp[j][k], dp[j - arr[i].w][k] + arr[i].x);
 88                         }
 89                     }
 90                 }
 91             }
 92
 93             is_s = false;
 94         }
 95
 96         int ans = 0;
 97
 98         rep(i, 0, m_num) ans = max(ans, dp[W][i]);//遍历费用是W的dp最好值,及为最大攻击力
 99
100         cout << ans << endl;
101     }
102
103
104     return 0;
105 }

原文地址:https://www.cnblogs.com/SSummerZzz/p/11163795.html

时间: 2024-12-15 16:03:23

2018年东北地区赛S - Problem I. Spell Boost HDU - 6508的相关文章

HDU 5924 Mr. Frog’s Problem 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)

Mr. Frog's Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 312    Accepted Submission(s): 219 Problem Description One day, you, a clever boy, feel bored in your math class, and then fall

2016 CCPC 东北地区重现赛

1. 2016 CCPC 东北地区重现赛 2.总结:弱渣,只做出01.03.05水题 08   HDU5929 Basic Data Structure    模拟,双端队列 1.题意:模拟一个栈的操作,并在每次询问时,计算栈项到栈底元素nand位运算的值. 2.总结:思路就是看距离栈底最近的0的后面1的个数的奇偶.试了好多种办法,最后还是双端队列简便.总之,贼恶心的题.. #include<iostream> #include<cstring> #include<cmath

HDU 5923 Prediction(2016 CCPC东北地区大学生程序设计竞赛 Problem B)

题目链接  2016 CCPC东北地区大学生程序设计竞赛 B题 题意  给定一个无向图和一棵树,树上的每个结点对应无向图中的一条边,现在给出$q$个询问, 每次选定树中的一个点集,然后真正被选上的是这些点以及这些点的所有祖先. 只有标号在树中真正被选上的点代表的这些原图中的边是存在的,这样就构成了一个新的图.求这个图的连通块个数. dfs整棵树,记$f[x]$为若$x$以及$x$的所有祖先被选上,那么构成的新的图的并查集) 这个实现比较简单,搜索的时候打上标记,回来的时候撤销即可. 这样预处理的

HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 524    Accepted Submission(s): 151 Problem Description TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams abou

HDU 5927 Auxiliary Set 【DFS+树】(2016CCPC东北地区大学生程序设计竞赛)

Auxiliary Set Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 873    Accepted Submission(s): 271 Problem Description Given a rooted tree with n vertices, some of the vertices are important. An a

HDU 5922 Minimum’s Revenge 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)

Minimum's Revenge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 283    Accepted Submission(s): 219 Problem Description There is a graph of n vertices which are indexed from 1 to n. For any pai

2018 数学建模美国赛思路

2018 数学建模 美国赛 D 建模思路 和文章大纲 题目 2018 ICM Problem D: Out of Gas and Driving on E (for electric, not empty) For both environmental and economic reasons, there is global interest in reducing the use of fossil fuels, including gasoline for cars. Whether mo

东北地区ACM竞赛总结-2013.6.11

回到沈阳已经两天,每次去比赛回来总会很疲惫,7号晚上的火车其实还可以路上大家都很开心,斗地主谁是卧底整个车厢基本都是我们的声音,吐槽一下我们居然买到了十三张上铺的票,一张下铺都没有,但是跟回来比还是很好的,中间还碰到了大连海事辽宁科技沈阳化工,各种欢乐啦,最后找到了一个牡丹江的本地人唠了一下当地有什么好玩的,她给我们首推的是镜泊湖,可惜没去上,之后他说江滨公园还是可以的最后去看了一下,感觉还可以吧,唯一的感觉就是热,8号热身赛一共六道题,基本都是搞笑娱乐题,小水了四道攒了一下人品,9号正式赛一共

2018冬令营模拟测试赛(三)

2018冬令营模拟测试赛(三) [Problem A]摧毁图状树 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 这题没想到贪心 QwQ,那就没戏了-- 贪心就是每次选择一个最深的且没有被覆盖的点向上覆盖 \(k\) 层,因为这个"最深的没有被覆盖的点"不可能再有其它点引出的链覆盖它了,而它又