【CF】E. Anya and Cubes(双向DFS)

来源:互联网 发布:网络性与爱 第一季 编辑:程序博客网 时间:2024/05/13 21:44

根据题意的话每次递归分3种情况

一共最多25个数,时间复杂度为3^25,太大了

我们可以分2次求解第一次求一半的结果,也就是25/2 = 12,记录结果

之后利用剩余的一半求结果 s-结果 = 之前记录过的结果 就可以

时间复杂度降低为 3 ^ (n/2+1)

题目链接:http://codeforces.com/contest/525/problem/E

#include<set>#include<map>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const int maxn = 33;set<LL>vis;map<LL,int>cnt[maxn];int n,kk,a[maxn];LL  ans = 0;LL  vk[20],s;void dfs1(int now,int v,int k,LL value){    if(value > s) return;    if(now == v){        vis.insert(value);        cnt[k][value]++;        return;    }    int e = a[now];    if(e <= 18 && k < kk)        dfs1(now + 1,v,k + 1,value + vk[e]);    dfs1(now + 1,v,k,value + (LL)e);    dfs1(now + 1,v,k,value);    return;}void dfs2(int now,int v,int k,LL value){    if(value > s) return;    if(now == v){        LL z = s - value;        if(vis.count(z)){            int _k = kk - k;            for(int i = 0; i <= _k; i++)                ans += cnt[i][z];        }        return;    }    int e = a[now];    if(e <= 18)        dfs2(now + 1,v,k + 1,value + vk[e]);    dfs2(now + 1,v,k,value + (LL)e);    dfs2(now + 1,v,k,value);}int main(){    vk[0] = 1;    for(int i = 1; i <= 18; i++) vk[i] = vk[i - 1] * i;    scanf("%d%d%I64d",&n,&kk,&s);    for(int i = 0; i < n; i++)        scanf("%d",&a[i]);    dfs1(0,n/2,0,0L);    dfs2(n/2,n,0,0L);    printf("%I64d\n",ans);    return 0;}

0 0
原创粉丝点击