• 「LuoguT36048」 Storm in Lover


    Description


    平成二十四年(2012年),5月11日,东京,某弓道场。

    “呐,呐,海未酱,你听说了吗?几天后的那场弓道大会?啊—!”橙发少女兴奋地拿着一张传单一样的纸跑向蓝发少女。由于过于兴奋,橙发在跑过大门的时候一不小心,被门槛绊了一跤。

    然而,蓝发少女站立着,手上拿着弓箭,似乎她的世界里并没有橙发少女。

    她将弓抬起。拉弓;弓满;箭出。

    可惜,离红心偏了一点。

    蓝发少女本来的激动瞬间平静了下来,眼神仿佛有些游离。恍惚之间,这时才注意到摔倒的橙发和她手中的传单。

    “啊……穗乃果,抱歉。我现在没什么心情,让我一个人静一会吧。”

    “海未酱……”

    “……事情就是这样。绘里酱有没有什么能让海未酱振作起来的方法呢?”穗乃果出来以后,碰到了她们的学生会长,绚濑绘里,于是把海未没有干劲事情告诉了她。

    “这的确是个问题呢。……说起来,我听说前几天海未常用的那把弓坏了,现在用的如果是新弓的话,或许她需要一段时间熟练一下呢。”绘里回忆了一下,提议让海未多多练习一下新的弓。
    题目描述

    海未面前现在有n个靶子。按照绘里的指示,海未需要把这n个靶子全部射穿才行。

    一开始,海未的精力为m,力度为a。每射穿一个靶子,海未对弓的熟练度就会上升,此时力度会增加b。

    每个靶子都有一个单独的耐久度d[i],每次受到海未的攻击,靶子的耐久度都会减少海未当前的力度的值。当靶子的耐久度为0或0以下时,靶子被破坏。但是,如果海未在一次射箭后并没有射穿这个靶子,海未的精力会减少c[i]。如果海未通过一次射箭破坏了靶子,她的精力不会受到影响。

    海未可以自由地选择射靶子的顺序。请问,海未是否能够通过合理地安排射靶子的顺序,使得她能够将这些靶子全部射穿?如果能,她完成任务后最多能省下多少精力?如果不能,她最多可以射穿多少个靶子?

    Input


    输入的第一行为四个正整数n,m,a,b。 接下来n行,每行两个正整数c[i],d[i]。

    Output


    输出的第一行仅包含一个字符串。请回答海未酱是否能完成全部射穿靶子的任务。 如果可以完成,输出“Yes”。 如果不能完成,输出“No” 。(两者均不包括引号)

    第二行仅包含一个正整数。若第一行为“Yes”,则你应输出所剩的最多精力值;若第一行为“No”,则你应输出最多能射穿的靶子数。

    Sample Input


    2 10 1 1
    1 4
    1 6

    Sample Output


    Yes
    5

    Hint


    对于30%的数据,n<=6。

    对于50%的数据,n<=9。

    对于70%的数据,n<=14。

    对于100%的数据,n<=21;1<=a,b,c,d<=32767。

    题解


    这种原创题 估计找到这里来的都是学弟学妹

    首先可见50%的数据是给暴搜的

    然后看数据范围以及最近被状压洗脑 决定像生日蛋糕一样暴搜加鬼畜剪枝试图A掉

    如果这种组合已经出现过,并且现在没有曾经优的话 剪掉。用二进制储存组合,2^21问题不大

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int c[27];
    int d[27];
    int n,m,a,b;
    inline int read()
    {
        char ch=getchar();
        int x=0;bool s=0;
        while(ch<'0'||ch>'9'){if(ch=='-')s=1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
        return s?-x:x;
    }
    inline void scan()
    {
        n=read(),m=read(),a=read(),b=read();
        for(register int i=0;i<n;++i)
        c[i]=read(),d[i]=read();
        return;
    }
    int f[2100007];
    int ans=0;
    int last=-1,maxx=0;//last存余量(初始化为-1可以兼具检测是否扫完功能) maxx存最多能打几块板
    void search(int x)
    {
        for(register int i=0;i<n;++i)
        if(!(ans&(1<<i)))
        {
            ans=ans|(1<<i);
            int mo;
            mo=d[i]%a==0?d[i]/a-1:d[i]/a;
            m-=mo*c[i];
            a+=b;
            if(x==n-1)last=max(last,m);
            else if(m<1)maxx=(m==0?max(maxx,x+1):max(maxx,x));
            else if(f[ans]<m){f[ans]=m;search(x+1);}
            a-=b;
            m+=mo*c[i];
            ans=ans^(1<<i);
        }
        return;
    }
    int main()
    {
        scan();
        //memset(f,127,sizeof(f));
        search(0);
        if(last==-1){printf("No
    %d",maxx);return 0;}
        printf("Yes
    %d",last);
        return 0;
    }

    以及代码中有很多莫名其妙的表达方法

    是我跟出题人pb大爷为了把90卡成100花了一个小时瞎几巴乱调的

    /最后还是A啦2333

  • 相关阅读:
    oracle 认证方式
    Oracle
    深入理解Java的接口和抽象类
    mongoDB的学习【小白的福音】
    对于vertical-align的学习
    flex的学习 flexBox的学习
    用伪类添加翘边阴影::before和::after
    icon小图标
    url 中的 ? 和 & 还有 # 的作用
    解决img的1px空白问题
  • 原文地址:https://www.cnblogs.com/qwerta/p/9379755.html
Copyright © 2020-2023  润新知