【链接】 我是链接,点我呀:)

【题意】

在这里输入题意

【题解】

每个数字有3种选择。
1.选中它。
2.选中它且加阶乘符号
3.不选中它(即计算和的时候不考虑它)

如果我们直接暴力写的话复杂度是\(3^{25}\)

寻求优化。

我们可以用Meet-in-the-middle这个方法。

先求出1..n/2这些数字的组合方式。

用map<ll,ll> dic[25]来存它们的和。

dic[i][j]表示前n/2个数字中选了i个【2】状态的数字,和为j的方案数。

则我们再穷举n/2+1..n这些数字的选择情况。

得到了和sum以及【2】状态的数字个数cnt之后。

答案累加\(∑_0^{k-cnt}dic[i][m-sum]\)

这样复杂度就是\(O(3^{12})\)级别的了。

完全可以接受了

(n=1的时候,n/2等于0,如果你的dfs里面写的条件是now==n/2,应该把它改为now>=n/2,如果不这么改的话,dic[0][0]=1这个会漏掉,

然后右半边就可能会漏解了)

【代码】

#include <bits/stdc++.h>
#define ll long long
using namespace std; const int N = 1e6;
const int M = 25;
const int MM = 200e4; int n,k,a[M+10],bo[M+10],tt;
ll pre[M+10],m,ans;
vector<ll>b[M+1]; int get_num(int cnt,ll x){
int l = 0,r = b[cnt].size()-1,temp1=-1,temp2=-1; while (l <= r){
int mid = (l+r)>>1;
if (x<=b[cnt][mid]){
temp1 = mid;
r = mid-1;
}else l = mid+1;
} l = 0,r = b[cnt].size()-1;
while (l <= r){
int mid = (l+r)>>1;
if (x>=b[cnt][mid]){
temp2 = mid;
l = mid+1;
}else r = mid-1;
} if (temp1==-1 || temp2 ==-1 || b[cnt][temp1]!=x) return 0;
else return temp2-temp1+1;
} void dfs(int now,int ope){
int st,en;
if (ope==1)
st = 1,en = n/2;
else
st = n/2+1,en = n;
if (now>=en+1){
ll sum = 0;
int cnt = 0;
for (int i = st;i <= en;i++){
if (bo[i]==0) continue;
if (bo[i]==2){
if (a[i]>=19) return;
sum+=pre[a[i]];
cnt++;
}else sum+=a[i];
}
if (sum > m) return;
if (ope==1){
b[cnt].push_back(sum);
}else{
for (int i = 0;i <= k-cnt;i++) {
ans+=get_num(i,m-sum);
}
}
return;
} bo[now] = 0;
dfs(now+1,ope); bo[now] = 1;
dfs(now+1,ope); bo[now] = 2;
dfs(now+1,ope);
} int main()
{
#ifdef LOCAL_DEFINE
freopen("rush_in.txt","r",stdin);
#endif
ios::sync_with_stdio(0),cin.tie(0);
pre[0] = 1;
for (int i = 1; ;i++){
pre[i] = pre[i-1]*i;
if (pre[i]>1e16+10) break;
}
cin >> n >> k >> m;
for (int i = 1;i <= n;i++) cin >> a[i];
dfs(1,1);
for (int i = 0;i <= k;i++) sort(b[i].begin(),b[i].end());
dfs(n/2+1,2);
cout<<ans<<endl;
return 0;
}

最新文章

  1. EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射
  2. OpenVPN使用用户名/密码验证方式
  3. 【代码笔记】iOS-时间选择框
  4. javascript一些小问题
  5. AJAX-----10iframe模拟ajax文件上传效果原理2
  6. python文件和元组
  7. 一个简单的scrapy爬虫抓取豆瓣刘亦菲的图片地址
  8. CentOS6 下安装HP-LaserJet 1020打印机
  9. Spark Streaming官方文档学习--下
  10. mysql去除重复查询的SQL语句基本思路
  11. Entity Framework (二) 查询
  12. java教材
  13. bzoj 2244 [SDOI2011]拦截导弹(DP+CDQ分治+BIT)
  14. 转:PHP乱码问题,UTF-8(乱码)
  15. 按某个字段来分组、编号的row_number()函数
  16. 解决ansible首次连接host服务器需验证问题
  17. SQL Server 向数据库中创建表并添加数据
  18. 数据结构:链表 &gt;&gt; 链表按结点中第j个数据属性排序(冒泡排序法)
  19. Linux定时器工具
  20. ~递归递归(FBI树--蓝桥)

热门文章

  1. 自己封装js组件 - 中级中高级
  2. windows 快捷调用
  3. rest_framework 节流功能(访问频率)
  4. [codeforces 618 F] Double Knapsack (抽屉原理)
  5. 08:Challenge 1
  6. PostgreSQL Replication之第六章 监控您的设置(3)
  7. PostgreSQL 批量生成数据
  8. vue中计算小数保留两位小数
  9. 最小生成树(MST) prim() 算法 kruskal()算法 A - 还是畅通工程
  10. 学习Go语言之观察者模式