F

题目链接:https://vjudge.net/problem/CodeForces-1070F

具体思路:首先把所有的00放进去,然后对于10 和01 的取两个数目最小值t,排完序后将前t个加起来,然后再将剩余的看作一类,求一个最大加的数目就可以了。

关于为什么看作一类,第一个原因,剩下的的构成只能是只有00 ,或者(00,10)或者(01,00)或者(10)或者(01),这样就好分清楚剩下的最多加多少了,因为如果放入剩下的话,只能增加一种或者增加两种,所以取最大满足情况的前k项加起来就可以了。

AC代码:

#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<stack>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<stdio.h>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
# define maxn 500000+100
int a1[maxn],a2[maxn],aa[maxn],ff[maxn];
int tot[maxn];
bool cmp(int t1,int t2)
{
    return t1>t2;
}
int main()
{
    int n;
    scanf("%d",&n);
    int t1,t2;
    int num1=0,num2=0,num3=0,num4=0;
    for(int i=1; i<=n; i++)
    {
        scanf("%d %d",&t1,&t2);
        if(t1==11)
        {
            aa[++num1]=t2;
        }
        else if(t1==10)
        {
            a1[++num2]=t2;
        }
        else if(t1==1)
        {
            a2[++num3]=t2;
        }
        else if(t1==0)
        {
            ff[++num4]=t2;
        }
    }
    sort(a1+1,a1+num2+1,cmp);
    sort(a2+1,a2+num3+1,cmp);
    sort(ff+1,ff+num4+1,cmp);
    int sum=0;
    int m=0;
    int p1=0,p2=0;
    int temp=min(num2,num3);
    for(int i=1; i<=num1; i++)
    {
        sum+=aa[i];
    }
    m+=num1;
    p1+=num1;
    p2+=num1;
    for(int i=1; i<=temp; i++)
    {
        sum+=a1[i];
        sum+=a2[i];
    }
    m+=temp*2;
    p1+=temp;
    p2+=temp;
    int num=0;
    for(int i=temp+1; i<=num2; i++)
    {
        tot[++num]=a1[i];
    }
    for(int i=temp+1; i<=num3; i++)
    {
        tot[++num]=a2[i];
    }
    for(int i=1; i<=num4; i++)
    {
        tot[++num]=ff[i];
    }
    sort(tot+1,tot+num+1,cmp);
    int t=min(min(min(p1*2-m,p2*2-m),m),num);//取可加的数目
    for(int i=1; i<=t; i++)
    {
        sum+=tot[i];
    }
    printf("%d
",sum);
    return 0;
}

以后打组队赛得抓紧了,不能松懈,也尽量少和别的队交流,,,继续加油吧

原文地址:https://www.cnblogs.com/letlifestop/p/10262811.html