CH2401送礼物

Posted shl-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CH2401送礼物相关的知识,希望对你有一定的参考价值。

乍一看,我想爆搜,但是时间复杂度O(2^n),凉凉。

所以我们考虑优化,用双向搜索解决。

将读入的数据降序排列,从中间一分两半,对前一半进行一次枚举,枚举可能的情况,用一个数组记录并去重。

再枚举后半段的情况,并对每一种情况在左半部分进行一次二分查找即可。时间复杂度为O(2n/2log22n/2)≈O(n*2n/2)。

另外,一分两半的位置有讲究,如果仅仅mid=n/2的话会造成超时,通过大量数据测试,当mid=n/2+3时速度最快

可能是这种情况时时间复杂度稍微小一些吧……

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define int long long 
 6 inline int read() {
 7     int ret=0,f=1;
 8     char c=getchar();
 9     while(c<0||c>9) {if(c==-) f=-1;c=getchar();}
10     while(c<=9&&c>=0) ret=ret*10+c-0,c=getchar();
11     return ret*f;
12 }
13 using namespace std;
14 int w,n;
15 int a[50],ans,mid;
16 int x[1<<25],sum;
17 void calc(int now) {
18     int val=w-now;
19     int ret=upper_bound(x+1,x+sum+1,val)-x;
20     ret--;
21     ans=max(ans,x[ret]+now);
22 }
23 void dfs1(int now,int tot) {
24     if(now==mid) {
25         x[++sum]=tot;
26         return ;
27     }
28     dfs1(now+1,tot);
29     if(tot+a[now]<=w) dfs1(now+1,tot+a[now]);
30 }
31 void dfs2(int now,int tot) {
32     if(now==n+1) {
33         calc(tot);
34         return ;
35     }
36     dfs2(now+1,tot);
37     if(tot+a[now]<=w) dfs2(now+1,tot+a[now]);
38 }
39 bool cmp(int x,int y) {
40     return x>y;
41 }
42 signed main() {
43     w=read(); n=read();
44     for(int i=1;i<=n;i++) a[i]=read();
45     sort(a+1,a+n+1,cmp);
46     mid=n/2+3;
47     dfs1(1,0);
48     sort(x+1,x+sum+1);
49     sum=unique(x+1,x+sum+1)-(x+1);
50     dfs2(mid,0);
51     printf("%lld\n",ans);
52     return 0;
53 }
AC Code

 

以上是关于CH2401送礼物的主要内容,如果未能解决你的问题,请参考以下文章

CH2401送礼物

互相送礼物

TYVJ1340 送礼物

仿QQ空间送礼物功能

upc7834 送礼物

设计模式—代理模式