hdu 6396 Swordsman 贪心

hdu 6396

多校七最后一题,学会了那么多算法,结果贪心的题写不出,这次比赛竟然造成500名到800+名全部爆零,要不是第一题数据不严谨(标程都被hack),我也要爆零...

题意:初始值你有k个属性的攻击vi,有n个怪兽,每个怪兽有k种属性的血量ai,并且有k种属性的加成bi,当你的k种属性的值全部大于等于某只怪兽的k种属性的血量,你可以杀死他,并且你的攻击力vi会升级,每种属性的攻击力vi都会加上那只怪兽的bi,求你最多能杀死多少怪兽,且输出最终你的每种属性的攻击力。

思路:由于k最大为5,可以借助最多5个优先队列,每个优先队列qi保存的是所有怪兽的血量ai,先把所有怪兽存在第一个优先队列,然后从第一个优先队列开始,找出所有ai<=vi的怪兽并把它移到下一个优先队列vi+1,当到了最后一个队列,移出去的怪兽代表被杀死,然后更新vi,如果最后一个队列没有移除怪兽,代表已经杀不死任何怪兽了,循环结束。

#include
#include
#include
#include
#include
using namespace std;
const int maxn=2e5+10;
struct node
{
	int v,id;
	bool operator<(const node& rhs)const{
		return v>rhs.v;
	}
}tmp;
int a[maxn][11];
priority_queueq[6];
int ans[6];

#define reads(n) FastIO::read(n)
namespace FastIO {
    const int SIZE = 1 << 16;
    char buf[SIZE], obuf[SIZE], str[60];
    int bi = SIZE, bn = SIZE, opt;
    int read(char *s) {
        while (bn) {
            for (; bi < bn && buf[bi] <= ' '; bi++);
            if (bi < bn) break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        int sn = 0;
        while (bn) {
            for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
            if (bi < bn) break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        s[sn] = 0;
        return sn;
    }
    bool read(int& x) {
        int n = read(str), bf;
        
        if (!n) return 0;
        int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
        for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
        if (bf < 0) x = -x;
        return 1;
    }
};

int main()
{
	int T;
	reads(T);
	while(T--)
	{
		int n,k,cnt=0;
		reads(n);reads(k);
		for(int i=1;i<=k;i++)reads(ans[i]);
		for(int i=1;i<=k;i++)
		while(!q[i].empty())q[i].pop();
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=2*k;j++)
			reads(a[i][j]);
		}
		for(int i=1;i<=n;i++)
		q[1].push((node){a[i][1],i});
		while(1)
		{
			int ok=0;
			for(int i=1;i<=k;i++)
			while(!q[i].empty())
			{
				tmp=q[i].top();
				if(tmp.v<=ans[i])
				{
					q[i].pop();
					if(i==k)
					{
						cnt++;
						ok=1;
						for(int j=k+1;j<=2*k;j++)
						ans[j-k]+=a[tmp.id][j];
					}
					else
					{
						tmp.v=a[tmp.id][i+1];
						q[i+1].push(tmp);
					}
				}
				else break;
			}
			if(!ok)break;
		}
		printf("%d\n",cnt);
		for(int i=1;i

 

你可能感兴趣的:(算法----贪心)