zoukankan      html  css  js  c++  java
  • bzoj 1034 [ ZJOI 2008 ] 泡泡堂BNB —— 贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1034

    一开始想了个很麻烦的贪心做法,对于每个 a[i],找第一个大于它的 b 匹配……

    然后WA...因为这样好像没有利用不能第一次匹配的值使答案更优;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int const maxn=1e5+5;
    int n,a[maxn],b[maxn],mx,mn;
    bool vis1[maxn];
    priority_queue<int>q;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)scanf("%d",&b[i]);
        sort(a+1,a+n+1); sort(b+1,b+n+1);
        int t=1;
        for(int i=1;i<=n;i++)
        {
            while(b[t]<=a[i]&&t<=n)q.push(b[t]),t++;
            if(t>n)break;
            vis1[i]=1; t++;
        }
        for(int i=1;i<=n;i++)
        {
            if(vis1[i])continue;
            int x=q.top(); q.pop();
            if(a[i]==x)mn++;
            else mn+=2;
        }
        memset(vis1,0,sizeof vis1); 
        while(q.size())q.pop();
        t=n;
        for(int i=n;i;i--)
        {
            while(b[t]>=a[i]&&t)q.push(-b[t]),t--;
            if(!t)break;
            vis1[i]=1; t--; mx+=2;
        }
        for(int i=n;i;i--)
        {
            if(vis1[i])continue;
            int x=-q.top(); q.pop();
            if(a[i]==x)mx++;
        }
        printf("%d %d",mx,mn);
        return 0;
    }

    优美的正解贪心不是全局考虑,而是每次考虑最大值和最小值;

    如果最小值能盖过对方的最小值或最大值能盖过对方的最大值,就直接进行;

    不行就用自己的最小值匹配对方的最大值,让答案最优。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const maxn=1e5+5;
    int n,a[maxn],b[maxn];
    int solve(int a[],int b[])
    {
        int ans=0,l1=1,l2=1,r1=n,r2=n;
        while(l1<=r1&&l2<=r2)
        {
            if(a[l1]>b[l2])ans+=2,l1++,l2++;
            else if(a[r1]>b[r2])ans+=2,r1--,r2--;
            else ans+=(a[l1]==b[r2]),l1++,r2--;//
        }
        return ans;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)scanf("%d",&b[i]);
        sort(a+1,a+n+1); sort(b+1,b+n+1);
        printf("%d %d",solve(a,b),2*n-solve(b,a));
        return 0;
    }
  • 相关阅读:
    2019总结
    数据挖掘-挖掘频繁模式、关联和相关性:基本概念和方法
    Elasticsearch-删除数据
    Elasticsearch-更新现有文档
    Elasticsearch-如何识别一篇文档
    2019-10-25 记录
    信息、数据、知识之间的关系
    螺旋式上升,螺旋形理论
    触发
    书籍阅读
  • 原文地址:https://www.cnblogs.com/Zinn/p/9373266.html
Copyright © 2011-2022 走看看