zoukankan      html  css  js  c++  java
  • P4025 [PA2014]Bohater

    一句话题意:

    Link

    给你 (n) 只怪物,打每个怪物需要扣除一定的血量,打完之后会回复一些血量。

    你现在有初始血量 (z) 点,让你设计一种打怪方案是所有的怪的可以被打完。

    solution:

    一个很神奇的贪心。

    首先我们把每个怪物分为两类,一类是回血怪,打完之后能回血的那种,另一类就是掉血怪。

    我们把这两种怪物分开来考虑。

    一个显然的策略就是先打回血怪再打掉血怪,不然先打掉血怪的话,血都掉没了你还怎么打其他的怪。

    也就是说我们要先猥琐发育一波,等血量升高了(升满级了)再打掉血怪。

    考虑同种怪物之间怎么安排顺序:

    1.对于回血怪:

    我们要尽可能先打血量少的。假如说你先打回血量多的,遇到下面一组样例你就 GG 了。

    当前血量 (10) ,打 boss 掉血量 (100) ,回血量 (10000) 的。

    这种情况你发现他虽然回血量比较多,但是你打不动他。

    所以还是要先猥琐发育一波,等血量上来了,在打这个怪。

    2.对于掉血怪:

    一开始我是按血量从高到低排序的,可连交了几发都 (WA) 了,才发现这样写是不对的。

    这是因为你可能会遇到一种情况就是 一个怪物他血量比较高,但回血量少。

    这时候我们在打完所有的回血怪之后,第一个打他就会让我们的血量立刻降下来,导致后面的怪物都打不了。

    所以我们要先紧着回血多的怪物打,是我们的血量尽可能的保持一个很高的状态。

    然后这道题就做完了。

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define int long long
    int n,z,x,y,cnt1,cnt2;
    struct node
    {
    	int id,x,y;
    }a[100010],b[100010];
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
    	return s * w;
    }
    bool comp(node a,node b)
    {
    	return a.x < b.x;
    }
    bool cmp(node a,node b)
    {
    	return a.y > b.y;
    }
    signed main()
    {
    	n = read(); z = read();
    	for(int i = 1; i <= n; i++)
    	{
    		x = read(); y = read();
    		int tmp = y-x;
    		if(tmp >= 0)
    		{
    			a[++cnt1].id = i;
    			a[cnt1].x = x;
    			a[cnt1].y = y;
    		}
    		else 
    		{
    			b[++cnt2].id = i;
    			b[cnt2].x = x;
    			b[cnt2].y = y;
    		}
    	}
    	sort(a+1,a+cnt1+1,comp);
    	sort(b+1,b+cnt2+1,cmp);
    	for(int i = 1; i <= cnt1; i++)
    	{
    		z -= a[i].x;
    		if(z <= 0) { printf("NIE
    "); return 0;}
    		z += a[i].y;
    	}
    	for(int i = 1; i <= cnt2; i++)
    	{
    		z -= b[i].x;
    		if(z <= 0) { printf("NIE
    "); return 0;}
    		z += b[i].y;
    	}
    	printf("TAK
    ");
    	for(int i = 1; i <= cnt1; i++) printf("%lld ",a[i].id);
    	for(int i = 1; i <= cnt2; i++) printf("%lld ",b[i].id);
    	return 0;
    }
    
    
  • 相关阅读:
    mysql查询版本
    mysql导出bug备注
    linux查找文件
    linux 编译式安装nginx
    linux文件校验
    linux 编译式安装apache
    网络层
    数据链路层
    物理层
    servlet过滤器
  • 原文地址:https://www.cnblogs.com/genshy/p/13790045.html
Copyright © 2011-2022 走看看