2014.10.29模拟赛【买汽水】

1.     买汽水

【问题描述】

暑期集训一共N天,大家都辛苦了,Symbol准备给大家买汽水,但是钱只有M。

每天买汽水的花销都是不固定的,如果不够钱,买到的汽水不够大家一起喝,那样子不太好对不对?所以我们要买的话,就得让每个人都能喝到汽水要不我们那天就不买了。现在给出每天买汽水的花销,请问我们一共最多能够花掉Symbol多少钱呢?

暑假最多不超过40天,Symbol给大家花的钱最多有一亿。

 

【输入】

输入第一行有两个整数N,M。 1<=N<=40,0<=M<=100000000。

接下来一行有N个数,表示某一天的汽水花销。每天汽水的花销p<=100000000。

【输出】

输出一个整数,表示我们能够花掉Symbol多少钱。

【输入输出样例一】

drink.in

drink.out

3 10

1 2 3

6

【输入输出样例二】

drink.in

drink.out

4 10

4 3 5 11

9

【数据描述】

对于10%的数据,N<=10。

对于30%的数据,N<=20。

对于60%的数据,N<=30。

对于100%的数据,N<=40。

首先把前n/2个和后n-n/2个分开,这样两部分的大小基本上是一样大的

然后前面的直接暴力算出所有解,再算后20个的时候暴力完只要二分第一个小于m-tot的值更新答案就好了

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<deque>
 9 #include<set>
10 #include<map>
11 #include<ctime>
12 #define LL long long
13 #define inf 0x7ffffff
14 #define pa pair<int,int>
15 #define pi 3.1415926535897932384626433832795028841971
16 #define mod 1000007
17 using namespace std;
18 struct hashing{int next,v;}hash[2000010];
19 bool operator < (const hashing &a,const hashing &b){return a.v<b.v;}
20 int head[mod];
21 int n,m,tot,cnt,ans;
22 int a[100];
23 inline bool fnd(int u)
24 {
25     int s=u%mod;
26     for (int i=head[s];i;i=hash[i].next)
27         if (hash[i].v==u)return 1;
28     return 0;
29 }
30 inline void insert(int u)
31 {
32     int s=u%mod;
33     hash[++cnt].v=u;
34     hash[cnt].next=head[s];
35     head[s]=cnt;
36 }
37 inline int bsearch(int x)
38 {
39     int l=1,r=cnt,s=0;
40     while (l<=r)
41     {
42         int mid=(l+r)>>1;
43         if (hash[mid].v<=x){s=hash[mid].v;l=mid+1;}
44         else r=mid-1;
45     }
46     return s;
47 }
48 int main()
49 {
50     freopen("drink.in","r",stdin);
51     freopen("drink.out","w",stdout);
52     scanf("%d%d",&n,&m);
53     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
54     while (a[n]>m)n--;
55     if (n==0)
56     {
57         printf("0");
58         return 0;
59     }
60     sort(a+1,a+n+1,greater<int>());
61     sort(a+1,a+(n/2)+1);
62     sort(a+(n/2)+2,a+n+1);
63     for (int i=0;i<1<<(n/2);i++)
64       {
65           tot=0;
66           for (int j=1;j<=n/2;j++)
67           if (i & (1<<(j-1)))
68           {
69           tot+=a[j];
70             if(tot>m)break;
71           }
72         if (tot>m)continue;
73         if(fnd(tot))continue;
74         insert(tot);
75       }
76     sort(hash+1,hash+cnt+1);
77     for (int i=0;i<=1<<(n-n/2);i++)
78     {
79         tot=0;
80         for (int j=1;j<=n-n/2;j++)
81         if (i & (1<<(j-1)))
82         {
83             tot+=a[j+n/2];
84             if (tot>m)break;
85         }
86         if (tot>m)continue;
87         int find=bsearch(m-tot);
88         ans=max(ans,find+tot);
89     }
90     printf("%d
",ans);
91     return 0;
92 }
drink
——by zhber,转载请注明来源
原文地址:https://www.cnblogs.com/zhber/p/4060958.html