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

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

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

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

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

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

题目链接:

#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;}

不要等待机会,而要创造机会。

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

相关文章:

你感兴趣的文章:

标签云: