打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
NOIP训练营内部试题

吃东西

(eat)

Time Limit:2000ms   Memory Limit:1024MB

题目描述

一个神秘的村庄里有4家美食店。这四家店分别有A,B,C,D种不同的美食。LYK想在每一家店都吃其中一种美食。每种美食需要吃的时间可能是不一样的。

现在给定第1家店A种不同的美食所需要吃的时间a1,a2,…,aA。

    给定第2家店B种不同的美食所需要吃的时间b1,b2,…,bB。

以及c和d。

LYK拥有n个时间,问它有几种吃的方案。

 

输入格式(eat.in)

    第一行5个数分别表示n,A,B,C,D。

    第二行A个数分别表示ai。

    第三行B个数分别表示bi。

    第四行C个数分别表示ci。

    第五行D个数分别表示di。

 

输出格式(eat.out)

一个数表示答案。

 

输入样例

11 3 1 1 1

4 5 6

3

2

1

 

输出样例

2

 

对于30%的数据A,B,C,D<>

对于另外30%的数据n<>

对于100%的数据1<><><><><><>

AC代码


/*

    1024MB*1024*1024/4 = 225000000个int数组

    A和B   C和D

    A和B和C和D

    A和B中的一种   C和D的一种

    A和B  双重循环  来得到一个f[i]表示花了i这个时间有几种可能  A*B

    进行桶排序,把f按次序的放进x数组中,A*B种可能排个序

    C和D  双重循环  来得到一个g[i]表示花了i这个时间有几种可能  C*D 

    进行桶排序,把g按次序的放进y数组中,C*D种可能排个序

    A*B 一个数组x   C*D的一个数组y   查询存在多少对i,j,使得x[i]+y[j]<=n >

    x和y都是顺序的。

    

    x[1]  y[?]  一个前缀(1~p) 

    x[2]  y[??]  一个前缀(1~pp)  pp<>

    x[3]  y[???] 一个前缀(1~ppp)  ppp<>

    

    当一个规模解决不了的时候,分成两半  meet in the middle

*/

#include

#include

#include

#include

#include

#include

#include

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++)="">

    for (i=1; i<=b; i++)="">

    MAX=0;

    cnt=cntt=0;

    for (i=1; i<=a;>

        for (j=1; j<=b;>

            if (a[i]+b[j]<>

            {

                f[a[i]+b[j]]++;

                MAX=max(MAX,a[i]+b[j]);

            }

    for (i=0; i<=max;>

    while (f[i])

        {

            f[i]--;

            c[++cnt]=i;

        }


    for (i=1; i<=c; i++)="">

    for (i=1; i<=d; i++)="">

    MAX=0;

    for (i=1; i<=c;>

        for (j=1; j<=d;>

            if (aa[i]+bb[j]<>

            {

                f[aa[i]+bb[j]]++;

                MAX=max(MAX,aa[i]+bb[j]);

            }

    for (i=0; i<=max;>

    while (f[i])

        {

            f[i]--;

            cc[++cntt]=i;

        }

    for (i=cntt; i>=1; i--) if (c[1]+cc[i]<=n)>

    now=i;

    for (i=1; i<=cnt;>

    {

        ans+=now;

        while (now&& c[i+1]+cc[now]>n) now--;

    }

    cout<><>

    ans=0;

    return 0;

}


100分 meet in the middle

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
[SCOI2009] windy 数
C 字符串数组赋值
统计字母个数
2003年全国计算机等级考试四级上机题
#怎样发现均线粘合的股票# 写:MA5:...
三线粘合选股公式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服