ZOJ 3474 Taekwondo

来源:互联网 发布:subversion mac 编辑:程序博客网 时间:2024/05/16 15:55
Taekwondo

Time Limit: 2 Seconds      Memory Limit: 65536 KB

Alice is very fond of Taekwondo and he is also a member of Taekwondo Association of Zhejiang University. One day, his friends decide to compare with him. Now Alice must face all of his friends'challange, that is to say, if there are T friends, then he will take T matchs in just one day! Of course Alice has limited energe power, so he must carefully arrange the order of the T matchs and take optional strategy to win all the matchs.

Here are the rules of taekwondo match. Player must use available kicks to hit available position of his opponent's body. Different kick gets different points. To simplify this problem, we assume that Alice will use only 3 kinds of kicks, as shown below:

  1. Axe Kick:consume P1 energe power, get 3 points
  2. Back-Whirling Kick: consume P2 energe power, get 2 points
  3. Turning Kick: consum P3 energe power, get 1 points
P1P2P3 depends on the opponent and will be given in the input. For example, if the opponent is taller than Alice, then Axe Kick may consume more energe, but for a shorter opponent, it will be easier to use Axe Kick,thus consuming less energe.

If Alice wants to win a single match, he must get at least 7 points and guarantee that his enenge is above zero. After each match, Alice will have a chance to rest, and will recover R energe power, Ralso depends on different opponent. Alice's initial energe power is S , and after a rest, his energe power may be more than S, which is available. Remember that Alice can freely arrange the order of all the matches and he must win all the matches.

Input

The first line of the input is a single integer m, which is the number of test cases. In each case, fisrt there are two integers T (T≤22) and S (S≤100), indicating that there are T friends to compare with Alice and Alice's initial energe power is S. the following T lines each contain 4 integers: Pi1Pi2Pi3Ri, as described above. (0<=Pi1Pi2Pi3Ri≤100)

Output

For each case, you should output one line. If Alice can win all the matches, output the max energe power he can save at last. Otherwise,output "no".

Sample Input

22 10040 40 40 10020 70 10 1001 1040 40 40 100

Sample Output

130no

Hint

In case 1, Alice should compare with the second person first, consume 50 energe power (2 Axe Kick and 1 Turning Kick), recover 100, then compare with the first person, consume 120 (2 Axe Kick and 1 Turning Kick), recover 100, thus the answer is 130.


贪心,感觉是一个很好的题,WA了很多遍,最后参考的其他人的思路才AC的

关键点在于其与对手的比赛顺序的选择上,单纯的按最小消耗值或是体力恢复值或是二者的大小差值排序是不正确的,为保证其能和更多个对手比赛,应该先处理净体力值为正值的选手(就是比完后体力的恢复值减去其最小消耗值为正值),可以按其消耗值从小向大排列,这样可以保证一遍将净体力值为正值的对手全比完(前提是可以与对手进行比赛,否则体力不足跳出),然后再处理为负的值,为负的值则按回复值的由大至小进行排列,至于为什么这样排请参考某大神证明过程http://hi.baidu.com/aekdycoin/item/8249c815f31c3ef9756a84dc

代码如下:

#define test#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>using namespace std;struct power{    int p1, p2, p3, r;} team[24];struct point{    int r, con;} add[24], de[24];int r_cmp(const void *a, const void *b){    point *aa = (point *)a;    point *bb = (point *)b;    return aa->r < bb->r ? 1 : -1;}int con_cmp(const void *a, const void *b){    point *aa = (point *)a;    point *bb = (point *)b;    return aa->con > bb->con ? 1 : -1;}int differ(int i) // 数据量较小,可以枚举所有情况判断最小消耗值{    int _min=0x7FFFFFFF, a, b, c;    for(a=0; a <= 3; a++)        for(b=0; b <= 4; b++)            for(c=0; c <= 7; c++)                if(a*3 + b*2 + c >= 7)                    _min = min(_min,c*team[i].p3 + b*team[i].p2 + a*team[i].p1);    return _min;}int flag[24], s;int main(){#ifdef test    freopen("in.txt", "r", stdin);#endif    int m, t;    scanf("%d", &m);    while(m--)    {        int add_i = 0, de_i = 0;        scanf("%d%d", &t, &s);        for(int i = 1; i <= t; i++)        {            scanf("%d%d%d%d", &team[i].p1, &team[i].p2, &team[i].p3, &team[i].r);            int ans = differ(i);            if(team[i].r - ans >= 0)            {                add[add_i].r = team[i].r;                add[add_i++].con = ans;            }            else            {                de[de_i].r = team[i].r;                de[de_i++].con = ans;            }        }        qsort(add, add_i, sizeof(add[0]), con_cmp); // 净体力恢复值为正的按消耗值从小到大排序        qsort(de, de_i, sizeof(de[0]), r_cmp);  // 净体力恢复值为负的按恢复值从大到小排序        int ok = 1;        for(int i = 0;ok && i < add_i; i++)        {            if(s <= add[i].con)  // 若不满足条件,则跳出返回0,挑战失败                ok = 0;            s += add[i].r - add[i].con;        }        for(int i = 0; ok && i < de_i; i++)        {            if(s <= de[i].con)                ok = 0;            s += de[i].r - de[i].con;        }        if(ok)            printf("%d\n", s);        else            printf("no\n");    }    return 0;}


原创粉丝点击