• 【CZY选讲·吃东西】


    题目描述

    一个神秘的村庄里有4家美食店。这四家店分别有A,B,C,D种不同的美食。LYK想在每一家店都吃其中一种美食。每种美食需要吃的时间可能是不一样的。现在给定第1家店A种不同的美食所需要吃的时间a1,a2,…,aA。给定第2家店B种不同的美食所需要吃的时间b1,b2,…,bB。以及c和d。LYK拥有n个时间,问它有几种吃的方案。

    数据范围

    1<=n<=100000000,1<=A,B,C,D<=5000,0<=ai,bi,ci,di<=100000000。

    此题空间足够大,时间2s。

    Ps.不要在意复杂度,事实证明O(n)能过

    题解:
       ①时间复杂度能够承受:50002,因此考虑暴力先讲AB CD两组的组合结果求出来。

       ②对于得到的两个数组进行组合,首先肯定要排序。   

       ③排序使用桶排序O(n)。然后维护两个指针,一个在1数组开头,一个在2数组结尾。

       ④根据单调性,两个指针只会向相反方向移动,时间复杂度O(n)

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <cstring>
    using namespace std;
    int f[100000005],c[25000005],cc[25000005];
    int A,B,C,D,n,a[5005],b[5005],aa[5005],bb[5005],MAX,cnt,cntt,i,j,now;
    long long ans;
    int main()
    {
        freopen("eat.in","r",stdin);
        freopen("eat.out","w",stdout);
        scanf("%d%d%d%d%d",&n,&A,&B,&C,&D);
        if (n==0 && A==0 && B==0 && C==0 && D==0) return 0;
        for (i=1; i<=A; i++) scanf("%d",&a[i]);
        for (i=1; i<=B; i++) scanf("%d",&b[i]);
        MAX=0;
        cnt=cntt=0;
        for (i=1; i<=A; i++)
            for (j=1; j<=B; j++)
                if (a[i]+b[j]<=n)
                {
                    f[a[i]+b[j]]++;
                    MAX=max(MAX,a[i]+b[j]);
                }
        for (i=0; i<=MAX; i++)
        while (f[i])
            {
                f[i]--;
                c[++cnt]=i;
            }
    
        for (i=1; i<=C; i++) scanf("%d",&aa[i]);
        for (i=1; i<=D; i++) scanf("%d",&bb[i]);
        MAX=0;
        for (i=1; i<=C; i++)
            for (j=1; j<=D; j++)
                if (aa[i]+bb[j]<=n)
                {
                    f[aa[i]+bb[j]]++;
                    MAX=max(MAX,aa[i]+bb[j]);
                }
        for (i=0; i<=MAX; i++)
        while (f[i])
            {
                f[i]--;
                cc[++cntt]=i;
            }
        for (i=cntt; i>=1; i--) if (c[1]+cc[i]<=n) break;
        now=i;
        for (i=1; i<=cnt; i++)
        {
            ans+=now;
            while (now&& c[i+1]+cc[now]>n) now--;
        }
        cout<<ans<<endl;
        ans=0;
        return 0;
    }//czy020202

    终点其实是被彻底忘记,旅程不过是场善意的烛骨铭心。

    你可曾记得我的孤寂,我们早已在起点各奔东西······ ——————汪峰《地心》

  • 相关阅读:
    emoji表情,直接存入数据库报错,,出现java.sql.SQLException: Incorrect string value: 'xF0x9Fx98x8ExF0。。。。。。
    Springmvc的服务端数据验证-----Hibernate Validator
    HashMap
    Treeset的两种排序方法(自然排序和比较器排序)
    Java设计模式之适配器模式
    Java中的三种工厂模式
    构造方法私有化_骰子
    Java中equals的覆盖
    HttpClient请求
    JAVA的单例模式与延时加载
  • 原文地址:https://www.cnblogs.com/Damitu/p/7654414.html
Copyright © 2020-2023  润新知