题意:

一个人他有一定的血,有一些怪物,他去杀怪物,有的怪物杀死他后还可以在不费自己血的情况下任意杀死一些怪物,问你他最多杀死多少怪物,在最多杀怪前提下最好用多少血,(大体题意是这样).

思路:

首先我们把怪物分成两个集合,A一个是杀死他后可以免费杀死其他人的,B另一个是杀死他后不能免费杀死其他人的,分析下我们会发现,A集合我们只要杀死其中一个人就可以免费杀死其他人(肯定杀费血最少的),而且很有可能会攒下一些杀死B集合的机会.

其实无非两种情况,杀A集合的和不杀A集合的,如果杀选择杀A集合的那么我们肯定全杀掉,而花费的血就是A集合中血最少的那个,然后我们再把出了刚刚杀的那个以外,和B集合的所有放在一起排序称为C,杀完A集合后会剩下一下免费杀人的机会,我们用这些机会去杀C中的人,既然是免费的肯定从最大的开始杀,杀完后如果没杀没的话我们就用自己的血从小的开始在接着杀,一直杀到自己血没活着敌人没了未知,这是第一种情况,第二种情况是不杀A集合的,只杀B集合的,这种好办,直接把B排序一便,从小的开始能杀多少杀多少,最后在两种方案中选择一个最优的输出来就行了...

/*

1 只杀bi为0的 ,排序下,直接杀就行了;

2 杀bi不为0的 ,先杀死最小的那个bi不为0的,然后得到 s = b1 + b2 + b3 +++

然后在杀死其余的 n1 + n2 - 1 - s 的怪,就ok了; 

*/

#include<stdio.h> 

#include<algorithm>

#define N 100000 + 100

using namespace std;

typedef struct

{

   int xp ,hp;

}NODE;

NODE node1[N] ,node2[N];

bool camp(NODE a ,NODE b)

{

   return a.hp < b.hp;

}

int main ()

{

   int t ,i ,n ,v ,n1 ,n2;

   int ans1_n ,ans2_n ,ans1_hp ,ans2_hp;

   int cas = 1 ,s;

   scanf("%d" ,&t);

   while(t--)

   {

      scanf("%d %d" ,&n ,&v);

      n1 = n2 = s = 0; 

      NODE temp;

      for(i = 1 ;i <= n ;i ++)

      {

         scanf("%d %d" ,&temp.hp ,&temp.xp);

         if(temp.xp)

         {

            node2[++n2] = temp;

            s += temp.xp;

         }

         else

         node1[++n1] = temp;

      } 

      ans1_n = ans1_hp = 0;

      sort(node1 + 1 ,node1 + n1 + 1 ,camp);

      int vv = v;

      for(i = 1 ;i <= n1 ;i ++)

      {

         if(vv < node1[i].hp) break; 

         ans1_n ++;

         ans1_hp += node1[i].hp;

         vv -= node1[i].hp;

      }

         

      sort(node2 + 1 ,node2 + n2 + 1 ,camp);

         

      if(v < node2[1].hp)

      {

         printf("Case %d: %d %d\n" ,cas ++ ,ans1_n ,ans1_hp);

         continue;

      }

         

      ans2_n = 1;

      ans2_hp = node2[1].hp;

      v -= node2[1].hp;

         

      if(s >= n1 + n2 - 1)

      {

         ans2_n = n1 + n2;

         if(ans1_n > ans2_n || ans1_n == ans2_n && ans1_hp < ans2_hp)

         printf("Case %d: %d %d\n" ,cas ++ ,ans1_n ,ans1_hp);

         else

         printf("Case %d: %d %d\n" ,cas ++ ,ans2_n ,ans2_hp);

         continue;

      }

        

      for(i = 2 ;i <= n2 ;i ++)

      node1[++n1] = node2[i];

         

      sort(node1 + 1 ,node1 + n1 + 1 ,camp);

      n1 -= s;

      vv = v;   

      ans2_n += s; 

      for(i = 1 ;i <= n1 ;i ++)

      {

         if(vv < node1[i].hp) break;

         vv -= node1[i].hp;

         ans2_n ++;

         ans2_hp += node1[i].hp;

      }

         

      if(ans1_n > ans2_n || ans1_n == ans2_n && ans1_hp < ans2_hp)

      printf("Case %d: %d %d\n" ,cas ++ ,ans1_n ,ans1_hp);

      else

      printf("Case %d: %d %d\n" ,cas ++ ,ans2_n ,ans2_hp);

   }

   return 0;

}

hdu4415 不错的想法题的更多相关文章

  1. HDU 4972 Bisharp and Charizard 想法题

    Bisharp and Charizard Time Limit: 1 Sec  Memory Limit: 256 MB Description Dragon is watching NBA. He ...

  2. CodeForces 111B - Petya and Divisors 统计..想法题

    找每个数的约数(暴力就够了...1~x^0.5)....看这约数的倍数最后是哪个数...若距离大于了y..统计++...然后将这个约数的最后倍数赋值为当前位置...好叼的想法题.... Program ...

  3. HDU - 5806 NanoApe Loves Sequence Ⅱ 想法题

    http://acm.hdu.edu.cn/showproblem.php?pid=5806 题意:给你一个n元素序列,求第k大的数大于等于m的子序列的个数. 题解:题目要求很奇怪,很多头绪但写不出, ...

  4. hdu 5063 不错的小想法题(逆向处理操作)

    题意:       刚开始的时候给你一个序列,长度为n,分别为a[1]=1,a[2]=2,a[3]=3,a[4]=4...a[n]=n,然后有4种操作如下: Type1: O 1 call fun1( ...

  5. HDU - 5969 最大的位或 想法题

    http://acm.hdu.edu.cn/showproblem.php?pid=5969 (合肥)区域赛签到题...orz 题意:给你l,r,求x|y的max,x,y满足l<=x<=y ...

  6. hdu3006 状态压缩+位运算+hash(小想法题)

    题意:        给了n个集合,问你这n个集合可以组合出多少种集合,可以自己,也可以两个,也可以三个....也可以n个集合组在一起. 思路:       是个小想法题目,要用到二进制压缩,位运算, ...

  7. poj1852 Ants ——想法题、水题

    求最短时间和最长时间. 当两个蚂蚁相遇的时候,可以看做两个蚂蚁穿过,对结果没有影响.O(N)的复杂度 c++版: #include <cstdio> #define min(a, b) ( ...

  8. HDU 4193 Non-negative Partial Sums(想法题,单调队列)

    HDU 4193 题意:给n个数字组成的序列(n <= 10^6).求该序列的循环同构序列中,有多少个序列的随意前i项和均大于或等于0. 思路: 这题看到数据规模认为仅仅能用最多O(nlogn) ...

  9. CodeForces - 156B Suspects 逻辑 线性 想法 题

    题意:有1~N,n(1e5)个嫌疑人,有m个人说真话,每个人的陈述都形如X是凶手,或X不是凶手.现在给出n,m及n个陈述(以+x/-X表示)要求输出每个人说的话是true ,false or notd ...

随机推荐

  1. LeetCode-133克隆图(图的遍历+深拷贝概念)

    克隆图 LeetCode-133 使用一个map来存储已经遍历的结点,这个存起来的结点必须是新new的才符合题意 /* // Definition for a Node. class Node { p ...

  2. 记录实践PC端微信防撤回实现过程(基于3.1.0.67版本)

    利用OD实现对PC端微信防撤回功能的实现 文章最后有一键补丁工具哦~ 准备工具 1.OD 2.PC微信客户端(3.1.0.67) 过程 1.运行微信客户端,不需要登录 2.运行OD,左上角选择附加进程 ...

  3. 2020年12月-第01阶段-前端基础-HTML常用标签

    1. HTML常用标签 首先 HTML和CSS是两种完全不同的语言,我们学的是结构,就只写HTML标签,认识标签就可以了. 不会再给结构标签指定样式了. HTML标签有很多,这里我们学习最为常用的,后 ...

  4. mysql 单机多实例重启数据库服务

    1.# cat db.txtbackend 3310base 3320storage 3330payment 3340promotion 3350 2.# cat restart_mysql_slav ...

  5. 【linux】驱动-1-环境准备

    目录 前言 1. 开发环境搭建 1.1 环境准备 1.1.1 安装工具 1.1.2 编译内核 1.1.2.1 获取内核源码 1.1.2.2 编译内核 1.2 内核驱动模块编译和加载 1.2.1 hel ...

  6. polay计数原理

    公式: Burnside引理: 1/|G|*(C(π1)+C(π2)+C(π3)+.....+C(πn)): C(π):指不同置换下的等价类数.例如π=(123)(3)(45)(6)(7),X={1, ...

  7. HDU-6862 Hexagon (2020HDU 多校 D8 H)

    1008 题意:半径为n的六边形(由半径为1的小六边形组成),从某一个小六边形出发有六个方向,找到一条转向次数最多的路径(用方向表示)遍历所有的六边形(一个六边形只访问一次). 题解:先画出n=3/4 ...

  8. 技术分享PPT整理(一):Bootstrap基础与应用

    最近在复习的时候总感觉有些知识点总结过,但是翻了一下博客没有找到,才想起来有一些内容是放在部门的技术分享里的,趁这个时候跳了几篇相对有价值的梳理一下,因为都是PPT,所以内容相对零散,以要点和图片为主 ...

  9. Linux性能优化:内存使用情况分析

    Blog:博客园 个人 目录 什么是内存 Linux内存回收机制 查看Linux内存情况 查看/proc/meminfo 使用free命令查看 Buffer和Cache Swap 内存泄漏和内存溢出 ...

  10. 基于SageMath的数学网站——本科毕业开发项目

    1 绪论 1.1研究背景 我国是一个拥有15亿人口的大国.其中,据2017年的统计,全国共有大学生2600万左右.如此数量众多的大学生,都会有着学习基础数理课程的需求.而在高校的数学教学中,教授最多最 ...