zoukankan      html  css  js  c++  java
  • 辽哥游戏

    Description
      张辽是一个长发飘飘的非常聪明的男孩,人人都称他为“辽哥”。辽哥喜欢玩一个有趣的电脑游戏。这个游戏开始的时候有n个碉堡,每个碉堡拥有一个防御值和一个附加值。玩家拥有一个初始的攻击力。如果玩家破坏了一个碉堡,则他能得到1分。每一次,辽哥会选择一个碉堡进行攻击。所有未被破坏的碉堡会联合起来防御,因此为了破坏那个碉堡,辽哥的攻击力必须大于或者等于所有未被破坏的碉堡的防御值之和,否则辽哥就会输掉游戏。如果辽哥成功破坏了那个碉堡,那么他的攻击力会变成那个碉堡的附加值,然后他可以选择下一个攻击的目标。
      由于辽哥拥有强大的编程能力,他不费吹灰之力就改写了那个游戏。在游戏开始前,他可以用炸弹消灭任意的碉堡,但是他不能通过这种方式来获得分数。问题来了,在游戏开始后,辽哥可以得到的最大分数是多少?

    Input
      输入包含多组(不超过100组)测试数据。
      每组测试数据的第一行包含一个正整数N,表示测碉堡的数目。接下来有N行,每行包括2个非负整数。第i+1行的2个整数分别表示第i个碉堡的防御值和附加值。最后还有一行,为一个整数,表示辽哥在游戏开始时的初始攻击力。
      输入以文件结束符结束。

    Output
      对每组数据,输出一行,为一个整数,表示辽哥可以拿到的最大分数。

    Sample Input
    3
    10 9
    25 30
    8 7
    50
    5
    100 230
    334 331
    33 288
    35 100
    334 22
    600

    Sample Output
    3
    4

    Data Constraint

    Hint
    【数据范围】
      对20%的数据,有N<=10;
      对40%的数据,有N<=100;
      对100%的数据,有N<=1000,每个碉堡的防御值和附加值均不会超过2000000。

    .
    .
    .
    .
    .
    分析
    开始时将若干个碉堡炸掉的操作有点难处理,我们考虑倒着做。
    设 f[i] 表示选的最后 i 个碉堡(任意选)的所需的最小攻击力。
    设第 j个碉堡的防御值和附加值分别为 b[j],d[j] ,
    则有 f[i]=min{f[i−1]+b[j]} (d[j]≥f[i−1])。
    还有碉堡要按 b+d从小到大排序(显然 b+d小的后选更优)。
    这样处理完之后选一个最大的 f[i] 使得初始攻击力 m≥f[i]即满足题意,输出此时的 i即可。
    时间复杂度 O(T∗n*n)。

    .
    .
    .
    .
    .
    程序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int n,f[2000];
    
    struct edge
    {
        int x,y;
    }a[2000];
    
    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 cmp(edge x,edge y)
    {
        return x.x+x.y<y.x+y.y;
    }
    
    int main()
    {
        while (scanf("%d",&n)!=EOF)
        {
            for (int i=1;i<=n;i++) 
            {
            	a[i].x=read();
    			a[i].y=read();
            } 
            memset(f,0X3f,sizeof(f));
            sort(a+1,a+1+n,cmp);
            f[0]=0;
            for (int i=1;i<=n;i++)
                for (int j=i;j>=1;j--)
                    if (a[i].y>=f[j-1]) f[j]=min(f[j],f[j-1]+a[i].x);
            for (int i=n,m=read();i>=0;i--)
                if (m>=f[i])
                {
                    printf("%d
    ",i);
                    break;
                }
        }
        return 0;
    }
    
  • 相关阅读:
    第一轮铁大树洞APP开发冲刺(3)
    记一次寒假小尝试心得体会
    小学四则运算口算练习app---No.7
    小学四则运算口算练习app---No.6
    小学四则运算口算练习app---No.5
    小学四则运算口算练习app---No.4
    小学四则运算口算练习app---No.3
    小学四则运算口算练习app---No.2
    小学四则运算口算练习app
    《需求工程--软件建模与分析》读书笔记03
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/11094929.html
Copyright © 2011-2022 走看看