atcoder abc 184 F - Programming Contest

meet-in-the-middle 基础算法(优化dfs)
meet−in−the−middle(又称折半搜索、双向搜索)对于n<=40的搜索类型题目,一般都可以采用该算法进行优化,很稳很暴力。
我们可以将n分成2部分这样可以将图片说明 ->图片说明 对于n=40的可以将复杂度降到n*logn左右 n->2^20;
然后我们通过dfs将前半段和后半段的所有不大于T的数存起来,在枚举一个的时候,判断另一个。

#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

typedef long long ll;
typedef double dl;

const int N = 1<<20;
const int M = 1e9+7;
const int INF = 0x7fffffff;

int n,m,T;
int a[N];
int b[N];
int c[N];

void dfs(int l,int r,int v,int d[],int &num)
{
    if(v>T) return ;
    if(l==r)
    {
        d[++num]=v;
        return ;
    }
    dfs(l+1,r,v+a[l],d,num);
    dfs(l+1,r,v,d,num);
}

void solve()
{
    scanf("%d%d",&n,&T);
    for(int i=1;i<=n;i++)    scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    int len=n/2+1;
    int b_num=0;
    dfs(1,len,0,b,b_num);
    sort(b+1,b+b_num+1);
    int c_num=0;
    dfs(len,n+1,0,c,c_num);
    sort(c+1,c+c_num+1);
    int ptr=c_num;
    int maxn=0; 
    for(int i=1;i<=b_num;i++)
    {
        while(b[i]+c[ptr]>T) ptr--;
        maxn=max(maxn,b[i]+c[ptr]);
    }
    printf("%d",maxn);
}

int main()
{
    solve();
}
全部评论

相关推荐

10-11 17:45
门头沟学院 Java
走吗:别怕 我以前也是这么认为 虽然一面就挂 但是颇有收获!
点赞 评论 收藏
分享
牛客410815733号:这是什么电影查看图片
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务