• Fountains CodeForces


      取得2个物品有3种情况:1.选一个c类型,一个d类型  2.选2个c类型  3.选2个d类型,分类讨论一下

      写了这题才发现二分还能这样用。

    #include<bits/stdc++.h>
    using namespace std;
    #define pii pair<int,int>
    vector<pii>a,b;
    int pre1[100000+10],pre2[100000+10];
    int main()
    {
        a.clear();
        b.clear();
        int n,c,d,flag=false,ans=0,tmp=0;
        cin>>n>>c>>d;
        //cout<<n<<" "<<c<<" "<<d<<endl;
        for(int i=1;i<=n;i++)
        {
            int bea,cos;
            char ch;
            cin>>bea>>cos;
            scanf(" %c",&ch);
            //cout<<bea<<" "<<cos<<" "<<ch<<endl;
            if(ch=='C')
                a.push_back(make_pair(cos,bea));
            else
                b.push_back(make_pair(cos,bea));
        }
        sort(a.begin(),a.end());
        sort(b.begin(),b.end());
        for(int i=0;i<a.size();i++)//第一种情况从c和d类型的物品里分别选一个能选到的最大val的东西
        {
            if(i==0)
                pre1[i]=a[i].second;
            else
                pre1[i]=max(pre1[i-1],a[i].second);
            if(a[i].first<=c)
                ans=max(ans,a[i].second);
        }
        for(int i=0;i<b.size();i++)
        {
            if(i==0)
                pre2[i]=b[i].second;
            else
                pre2[i]=max(pre2[i-1],b[i].second);
            if(b[i].first<=d)
                tmp=max(tmp,b[i].second);
        }
        /*
        for(int i=0;i<a.size();i++)
            cout<<a[i].first<<"  "<<a[i].second<<"      ";
        cout<<endl;
        for(int i=0;i<a.size();i++)
            cout<<pre1[i]<<"      ";
        cout<<endl;
        cout<<"****************************************"<<endl;
        for(int i=0;i<b.size();i++)
            cout<<b[i].first<<"  "<<b[i].second<<"      ";
        cout<<endl;
        for(int i=0;i<b.size();i++)
            cout<<pre2[i]<<"      ";
        cout<<endl;
        */
        if(ans&&tmp)
        {
            flag=true;
            ans+=tmp;
        }
        else
            ans=0;
        for(int i=1;i<a.size();i++)//第2种情况,从c类型的物品里选2件,过程是直接选一件,然后再二分找另外一件能取到最大价值的物品
        {
            if(a[i].first>=c)
                continue;
            int rest=c-a[i].first,low,up,mid,pos=-1;
            low=0;
            up=i-1;
            while(low<=up)
            {
                mid=(low+up)>>1;
                if(a[mid].first<=rest)
                {
                    pos=mid;
                    low=mid+1;
                }
                else
                    up=mid-1;
            }
            if(pos!=-1)
            {
                ans=max(ans,a[i].second+pre1[pos]);
                flag=true;
            }
        }
        for(int i=1;i<b.size();i++)//第3种情况,从d类型的物品里选2件,过程是直接选一件,然后再二分找另外一件能取到最大价值的物品
        {
            if(b[i].first>=d)
                continue;
            int rest=d-b[i].first,low,up,mid,pos=-1;
            low=0,up=i-1;
            while(low<=up)
            {
                mid=(low+up)>>1;
                if(b[mid].first<=rest)
                {
                    pos=mid;
                    low=mid+1;
                }
                else
                    up=mid-1;
            }
            if(pos!=-1)
            {
                ans=max(ans,b[i].second+pre2[pos]);
                flag=true;
            }
        }
        if(flag)
            cout<<ans<<endl;
        else
            cout<<0<<endl;
        return 0;
    }
  • 相关阅读:
    Fiddler的使用
    vue后台管理系统搭建
    有效的山脉数组
    从中序与后序遍历序列构造二叉树
    从前序与中序遍历序列构造二叉树
    最大二叉树
    填充每个节点的下一个右侧节点指针
    二叉树展开为链表
    翻转二叉树
    Java判断字符串是否为数字
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754916.html
Copyright © 2020-2023  润新知