原题: http://acm.nyist.net/JudgeOnline/problem.php?pid=1309
//nyoj 1309 特别难的贪心(看了大神的解题报告,看了好多次才明白)
//1.对技能处理:把每项技能转化为两个值,一个是对神龙sl的伤害,一个是对冰法斗士zz的伤害
//2.有两种情况zz是必赢,①有一个技能满足 冰冻时间fz>=冷却时间cd 且 此技能伤害d>0,则sl必死
// ②有一个技能满足 冰冻时间fz-2>=冷却时间cd 且存在某一个技能的d>0,则sl也必死
//3.如果两种必赢情况都不满足,则只能用贪心来选择技能,尽量让sl先死
// ①把每个技能按 神龙的伤害 和 zz伤害之比(sl/zz) 排序,从高到低
// ②排序后,每次选择zz的血量hp范围内,效率最高的技能来杀神龙
// 直到最后,每一个技能都杀不死神龙,那zz就只能失败NO了。
// 一旦过程中有一个技能可以杀死神龙,break跳出,宣告zz胜利YES。
//注意:每次使用技能,神龙总是先受到伤害。而且每个技能的发射速度都是瞬间的!
//贪心思想体现在,每次选取在zz血量范围内效率最高的技能。
//这题我不会,考虑的细节不够,而且贪心想法也错,看完大神的解题报告深有感悟,果然自己水平还是太低。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<stdlib.h>
#include<memory.h>
#include<set>
using namespace std;
struct J
{
int sl;
int zz;
}j[1000001];
int cmp(const void *aa,const void*bb)//把效率高的排前面
{
J a=*(J*)aa;
J b=*(J*)bb;
return a.sl*b.zz<a.zz*b.sl;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int HP,D;
int hp,n;
scanf("%d %d",&HP,&D);
scanf("%d %d",&hp,&n);
int flag1=0; //0表示刚刚出现j[i].sl>0
int flag2=0;
int flag3=0;
for(int i=0;i<n;i++)
{
int d,fz,cd;
scanf("%d %d %d",&d,&fz,&cd);
if(fz>=cd && d>0)
{
flag1=1;
}
if(fz>cd){
flag2=1;
}
if(d>0){
flag3=1;
}
j[i].sl=d;
j[i].zz=D*(cd-fz);
}
if(flag1|| flag2&&flag3)
{
printf("YES\n");
}else{
qsort(j,n,sizeof(j[0]),cmp);
int i;
while(HP>0)
{
for(i=0;i<n;i++)//遍历每一个技能
{
if(j[i].sl==0)continue;
if(j[i].sl>=HP){//如果这个技能可以一刀kill神龙,break跳出
HP=0;
break;
}
if(j[i].zz<hp){ //选取自己血量范围内效率最高的技能。
HP-=j[i].sl;
hp-=j[i].zz;
break;
}
}
if(i==n){ //没有一个技能可以杀死神龙
break;
}
}
if(HP==0){
printf("YES\n");
}else{
printf("NO\n");
}
}
}
return 0;
}