zoukankan      html  css  js  c++  java
  • [USACO14DEC]后卫马克Guard Mark

    看到没有完整的贪心题解,本蒟蒻决定来补充一发(没有完整证明的贪心是不圆满的)

    不知道大家做过NOIP2012国王游戏没,这两道题思路相似

    进入正题,看着就像贪心的一道题

    怎么贪,按height,strength,weight排序好像都不合适

    试图分析相邻两项交换的影响

    一个位置的承重量可以这样表示Resti=Strengthi-∑Weightj(j>i)

    同理,它的下一项可以如下表示Resti+1=Strengthi+1-∑Weightj(j>i+1)

    相邻两项交换后是这样的

    Resti=Strengthi+1-Weighti-∑Weigthj(j>i+1)

    Resti+1=Strengthi-∑Weightj(j>i+1)

    我们要使稳定强度最大,即最大化Min(Resti)

    还是考虑这相邻两项,我们考虑是否交换就转化为了判断这个东西

    max(min(PreResti,PreResti+1),min(NextResti,NextResti+1))

    为了简化式子

    我们给上述每项同加∑Weightj(j>i+1)

    上式化简为

    max((Pre)min(Strengthi-Weighti+1,Strengthi+1}),(Next)min(Strengthi+1-Weighti,Strengthj))

    观察到

    Strengthi>=Strengthi-Weighti+1,Strengthi+1>Strengthi+1-Weighti

    如果

    Strengthi+1-Weighti<=Strengthi-Weighti+1<=Strengthi

    那么Next中min的一定是Strengthi+1-Weighti,而Pre中每一项都大于它,即交换前总优于交换后

    反之,交换后优于交换前

    移项得,

    Strengthi+Weighti>=Strengthi+1+Weighti+1

    时,交换前更优

    所以我们按照Strength+Weight从大到小排序即可

    然后2^n枚举选择哪些牛,对于每种情况,求出Rest的最小值,然后在其中取最大即可

    上代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct node{
        int h,w,s;
    }a[30];
    int n,h;
    bool c[30];
    long long ans=-1;
    bool cmp(const node &x,const node &y)
    {
        return x.w+x.s>y.w+y.s;
    }
    void dfs(int x,int ch)
    {
        c[x]=ch;
        if(x==n)
        {
            long long tmp=1e9,len=0;
            for(int i=1;i<=n;i++)
                if(c[i])
                {
                    len+=a[i].h;
                    long long sum=0;
                    for(int j=i+1;j<=n;j++)
                        sum+=c[j]?a[j].w:0;
                    tmp=min(tmp,a[i].s-sum);
                }
            if(len>=h)
                ans=max(ans,tmp);
            return;
        }
        dfs(x+1,1);
        dfs(x+1,0);
    }
    int main()
    {
        scanf("%d%d",&n,&h);
        for(int i=1;i<=n;i++)
            scanf("%d%d%d",&a[i].h,&a[i].w,&a[i].s);
        sort(a+1,a+n+1,cmp);
        dfs(0,0);
        
        if(ans==-1)
            printf("Mark is too tall
    ");
        else
            printf("%lld
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    牛客寒假6-I 导航系统
    牛客寒假6-C汉诺塔
    P1282 多米诺骨牌【dp】
    VisualStudio中C++程序输出一闪而过的解决方案
    【网络流24题】【LOJ6224】深海机器人问题(最大费用最大流)
    【网络流24题】【LOJ6013】负载平衡(环形纸牌均分,最小费最大流)
    【网络流24题】【LOJ6010】数字梯形(费用流)
    【网络流24题】【LOJ6000】搭配飞行员(二分图最大匹配,最大流Dinic)
    路由器相关
    PC启动原理
  • 原文地址:https://www.cnblogs.com/ivanovcraft/p/9649230.html
Copyright © 2011-2022 走看看