Codeforces Round #297 (Div. 2)E. Anya and Cubes 折半搜索
来源:互联网 发布:windows错误1503 编辑:程序博客网 时间:2024/05/17 22:08
题目连接:
http://codeforces.com/contest/525/problem/E
题意:
n个数,k个魔法棒,s为所求的数,然后让你找有多少种方法,能够使的这n个数之和为s,其中一个魔法棒可以使的一个数变成他的阶乘。
题解:
第一种:http://blog.csdn.net/weizhuwyzc000/article/details/50043151
对于每一层,有3种决策: 不选这个数, 选择这个数, 选择这个数的阶乘。 递归深度最大25, 时间复杂度O(3^25), 太大了, 要想办法降低时间复杂度。 还记得之前的简化版吗? 我们在四个集合中每个集合选择一个数字相加,问是否等于一个数S, 我们的方法是预处理三个集合中所有的情况,然后二分。 该题也可以采取相同的策略: 进行两次dfs, 每次递归深度n/2,这样就成功将复杂度降低到O((3^13)*log(3^13)) 。 这是理论上界, 事实上这里面有很多重复的,时间复杂度并没有那么高。
第二种:http://www.cnblogs.com/qscqesze/p/4371851.html
折半搜索
对于每一个数,都有三种策略,拿,不拿,使用魔法棒
那么我们就直接折半搜索然后扔进一个map里面,然后就查询就好啦
13^3*12^3=3 796 416;
复杂度算的刚刚好呀= = (没看懂怎么算的
学到了 折半搜索降低复杂度 这个折半的意思是预先算出一半的结果,再从后一半找到sum-ans1。
还有就是map的运用 按first从小到大默认排序,如果first是结构体, 可以在结构体中写优先级的函数,map就会自动排序啦
代码一:
#include <bits/stdc++.h>using namespace std;typedef long long ll;#define mem(a) memset(a,0,sizeof(a))#define mp(x,y) make_pair(x,y)const int INF = 0x3f3f3f3f;const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}//////////////////////////////////////////////////////////////////////////const int maxn = 1e5+10;ll n,k,s;ll a[30],ans;ll p[30];struct node{ ll sum, y; node(ll ss=0, ll kk=0):sum(ss), y(kk) {} bool operator < (const node& rhs) const { if(sum==rhs.sum) return y<rhs.y; return sum < rhs.sum; }};map<node,int> mp;map<node,int>::iterator it;void dfs1(int nn,int kk,ll ss){ if(k < kk) return ; if(ss > s) return ; if(nn > n/2){ node t(ss,kk); mp[t]++; return ; } dfs1(nn+1,kk,ss); dfs1(nn+1,kk,ss+a[nn]); if(a[nn] <= 20) dfs1(nn+1,kk+1,ss+p[a[nn]]);}void dfs2(int nn,int kk,ll ss){ if(k < kk) return ; if(ss > s) return ; if(nn > n){ it = mp.lower_bound(node(s-ss,0)); for( ; it!=mp.end(); it++){ if(it->first.sum==s-ss && k-it->first.y >= kk) ans += it->second; if(it->first.sum != s-ss) break; } return ; } dfs2(nn+1,kk,ss); dfs2(nn+1,kk,ss+a[nn]); if(a[nn] <= 20) dfs2(nn+1,kk+1,ss+p[a[nn]]);}int main(){ p[1] = 1; for(int i=2; i<=20; i++) p[i] = i*p[i-1]; n = read(), k = read(), s = read(); for(int i=1; i<=n; i++) a[i] = read(); int mid = n/2; dfs1(1,0,0); dfs2(mid+1,0,0); cout << ans << endl; return 0;}
代码二:
#include <bits/stdc++.h>using namespace std;typedef long long ll;#define mem(a) memset(a,0,sizeof(a))#define mp(x,y) make_pair(x,y)const int INF = 0x3f3f3f3f;const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}//////////////////////////////////////////////////////////////////////////const int maxn = 1e6+10;struct node{ ll sum,key;}bef[maxn];ll p[30],cubes[30];ll n,k,s,cnt,ans;map<ll,ll> mp[30];map<ll,ll>::iterator it;void dfs1(ll nn,ll kk,ll ss){ if(ss > s) return ; if(kk > k) return ; if(nn > n/2){ bef[++cnt].sum = ss; bef[cnt].key = kk; return ; } dfs1(nn+1,kk,ss); dfs1(nn+1,kk,ss+cubes[nn]); if(cubes[nn] <= 20) dfs1(nn+1,kk+1,ss+p[cubes[nn]]);}void dfs2(ll nn,ll kk,ll ss){ if(ss > s) return ; if(kk > k) return ; if(nn > n){ mp[kk][ss]++; return ; } dfs2(nn+1,kk,ss); dfs2(nn+1,kk,ss+cubes[nn]); if(cubes[nn] <= 20) dfs2(nn+1,kk+1,ss+p[cubes[nn]]);}int main(){ n = read(), k = read(), s = read(); for(int i=1; i<=n; i++) cubes[i] = read(); p[1] = 1; for(int i=2; i<=20; i++) p[i] = i*p[i-1]; dfs1(1,0,0); dfs2(n/2+1,0,0); ans = 0; for(int i=1; i<=cnt; i++) for(int j=0; j<=k-bef[i].key; j++) ans += mp[j][s-bef[i].sum]; cout << ans << endl; return 0;}
- Codeforces Round #297 (Div. 2)E. Anya and Cubes 折半搜索
- Codeforces Round #297 (Div. 2)E. Anya and Cubes(折半搜索)
- E. Anya and Cubes (CF #297 (Div. 2) 折半搜索)
- E. Anya and Cubes (CF #297 (Div. 2) 折半搜索)
- Codeforces Round #297 (Div. 2)---E. Anya and Cubes
- Codeforces Round #297 (Div. 2) E - Anya and Cubes
- Codeforces Round #297 (Div. 2) E. Anya and Cubes
- Codeforces Round #297 (Div. 2) E Anya and Cubes
- Codeforces Round #297 (Div. 2) E Anya and Cubes
- Codeforces Round #297 (Div. 2)E. Anya and Cubes
- 【Codeforces Round #297 (Div. 2)】Codeforces 525E Anya and Cubes
- 中途相与法(Codeforces Round #297 (Div. 2)E - Anya and Cubes )
- Codeforces Round #297 (Div. 2) E题. Anya and Cubes (中途相遇法)
- Codeforces Round #297 (Div. 2) E. Anya and Cubes (双向DFS)
- Codeforces Round #297 (Div. 2) 525E Anya and Cubes(dfs)
- #297 (div.2) E. Anya and Cubes
- codeforces 525E E. Anya and Cubes( dp+折中搜索)
- Anya and Cubes - CodeForces 525 E dp
- 蓝桥杯省赛 方格填数C/C++
- Leetcode第一题<two sum>
- Redhat6.5利用yum快速搭建LAMP环境
- 强化学习(Reinforcement Learning, RL)初步介绍
- RMQ算法
- Codeforces Round #297 (Div. 2)E. Anya and Cubes 折半搜索
- PAT甲级1001. A+B Format (20)
- kaldi data preparation
- 大数据江湖之即席查询与分析(下篇)--手把手教你搭建即席查询与分析Demo
- ArcEngine 释放锁文件,彻底移除图层
- 在本地用命令行创建一个git仓库,并推送到远程
- 教你如何搭建一个超完美的服务端渲染开发环境
- 生成式对抗网络GAN汇总
- 层次聚类算法(一)