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

本文探讨了一种通过分治法优化递归算法复杂度的策略,具体实例来源于Codeforces竞赛中的一道难题。通过两次递归求解,将原问题的时间复杂度从(3^{25}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据题意的话每次递归分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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值