本文主要是介绍【CF】E. Anya and Cubes(双向DFS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
根据题意的话每次递归分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;
}
这篇关于【CF】E. Anya and Cubes(双向DFS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!