题目

Source

http://codeforces.com/contest/525/problem/E

Description

Anya loves to fold and stick. Today she decided to do just that.

Anya has n cubes lying in a line and numbered from 1 to n from left to right, with natural numbers written on them. She also has k stickers with exclamation marks. We know that the number of stickers does not exceed the number of cubes.

Anya can stick an exclamation mark on the cube and get the factorial of the number written on the cube. For example, if a cube reads 5, then after the sticking it reads 5!, which equals 120.

You need to help Anya count how many ways there are to choose some of the cubes and stick on some of the chosen cubes at most k exclamation marks so that the sum of the numbers written on the chosen cubes after the sticking becomes equal to S. Anya can stick at most one exclamation mark on each cube. Can you do it?

Two ways are considered the same if they have the same set of chosen cubes and the same set of cubes with exclamation marks.

Input

The first line of the input contains three space-separated integers n, k and S (1 ≤ n ≤ 25, 0 ≤ k ≤ n, 1 ≤ S ≤ 1016) — the number of cubes and the number of stickers that Anya has, and the sum that she needs to get.

The second line contains n positive integers ai (1 ≤ ai ≤ 109) — the numbers, written on the cubes. The cubes in the input are described in the order from left to right, starting from the first one.

Multiple cubes can contain the same numbers.

Output

Output the number of ways to choose some number of cubes and stick exclamation marks on some of them so that the sum of the numbers became equal to the given number S.

Sample Input

2 2 30
4 3
2 2 7
4 3
3 1 1
1 1 1

Sample Output

1
1
6

分析

题目大概说有n个数,从中选出若干个数,可以再从选择的数中选择不超过k个数让它们变为自身的阶乘,问有几种方案使得选出来的若干个数的和等于S。

将n个数分成两边,左边dfs不选、选、选且变为阶乘搜出所有方案,用map统计各个和的情况;右边一样,利用map更新答案。
不过,由于最后还要枚举更新答案,超时了;把左边搜索的数量增加一点,变为min(n/2+2,n)就过了。
看了下官方题解,题解说先用count()判断map有没有再用这样会快,果然快了1倍。

代码

#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std; long long S;
int n,m,a[26]; long long fact[20]={1}; long long ans; map<long long,int> cnt[26];
int tmp;
void dfs1(int x,int y,long long s){
if(s>S || y>m) return;
if(x==tmp){
++cnt[y][s];
return;
}
dfs1(x+1,y,s);
dfs1(x+1,y,s+a[x]);
if(a[x]<19) dfs1(x+1,y+1,s+fact[a[x]]);
} void dfs2(int x,int y,long long s){
if(s>S || y>m) return;
if(x==n){
for(int i=0; i+y<=m; ++i){
if(cnt[i].count(S-s)) ans+=cnt[i][S-s];
}
return;
}
dfs2(x+1,y,s);
dfs2(x+1,y,s+a[x]);
if(a[x]<19) dfs2(x+1,y+1,s+fact[a[x]]);
} int main(){
for(int i=1; i<20; ++i){
fact[i]=fact[i-1]*i;
}
scanf("%d%d%lld",&n,&m,&S);
for(int i=0; i<n; ++i){
scanf("%d",a+i);
}
tmp=min(n,n/2+2);
dfs1(0,0,0);
dfs2(tmp,0,0);
printf("%lld\n",ans);
return 0;
}

Codeforces525E Anya and Cubes(双向搜索)的更多相关文章

  1. Codeforces Round #297 (Div. 2)E. Anya and Cubes 折半搜索

    Codeforces Round #297 (Div. 2)E. Anya and Cubes Time Limit: 2 Sec  Memory Limit: 512 MBSubmit: xxx  ...

  2. Anya and Cubes 搜索+map映射

    Anya loves to fold and stick. Today she decided to do just that. Anya has n cubes lying in a line an ...

  3. Codeforces 525E Anya and Cubes

    http://codeforces.com/contest/525/problem/E 题意: 有n个方块,上面写着一些自然数,还有k个感叹号可用.k<=n 你可以选任意个方块,然后选一些贴上感 ...

  4. Anya and Cubes CodeForces - 525E (双端搜索)

    大意: 给定$n$元素序列$a$, 可以任选不超过$k$个$a_i$变换为$a_i!$, 求变换后任选若干元素和为S的方案数. 分成两块暴搜, 复杂度$O(3^{\frac{n}{2}})$ #inc ...

  5. codeforces E - Anya and Cubes 分块处理 暴力搜索

    说的是给了n个立方体,立方体从1标号到n,每个立方体上有一个数字, 你有 k 个机会 使得其中 k个数位他们自己的阶乘,(自然使用可以少于k次机会,每个立方体最多被使用1次) ,那么求出你从这n个立方 ...

  6. CF525E Anya and Cubes(meet in the middle)

    题面 给你\(n\)个数,\(n\le 26\)初始序列为\(a_i,0\le a_i\le 10^9\) 你有\(k\)个\(!\),每个\(!\)可以使序列中的一个数变成\(a_i!\) 例如\( ...

  7. [Codeforces Round #297 Div. 2] E. Anya and Cubes

    http://codeforces.com/contest/525/problem/E 学习了传说中的折半DFS/双向DFS 先搜前一半数,记录结果,然后再搜后一半数,匹配之前结果. #include ...

  8. Codeforces 525E Anya and Cubes 中途相遇法

    题目链接:点击打开链接 题意: 给定n个数.k个感叹号,常数S 以下给出这n个数. 目标: 随意给当中一些数变成阶乘.至多变k个. 再随意取一些数,使得这些数和恰好为S 问有多少方法. 思路: 三进制 ...

  9. 【Henu ACM Round#18 E】Anya and Cubes

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每个数字有3种选择. 1.选中它. 2.选中它且加阶乘符号 3.不选中它(即计算和的时候不考虑它) 如果我们直接暴力写的话复杂度是\ ...

随机推荐

  1. python内置函数

    python内置函数 官方文档:点击 在这里我只列举一些常见的内置函数用法 1.abs()[求数字的绝对值] >>> abs(-13) 13 2.all() 判断所有集合元素都为真的 ...

  2. 什么是pe系统

    Winpe全称 Windows Preinstall Environment,即“Windows 预安装环境”.是一个用于Windows 安装准备的最小操作系统. 基于保护模式下运行Windows X ...

  3. 学习.Net的经典网站

    学习.Net的经典网站 收藏 还不错推荐给大家 原文-- 名称:快速入门 地址:http://chs.gotdotnet.com/quickstart/ 描述:本站点是微软.NET技术的快速入门网站, ...

  4. Google 地图 API V3 之控件

    Google官方教程: Google 地图 API V3 使用入门 Google 地图 API V3 针对移动设备进行开发 Google 地图 API V3 之事件 Google 地图 API V3 ...

  5. solr suggest智能提示配置

    目录 配置文件 Java代码 遇到的问题 回到顶部 配置文件 solrconfig.xml <searchComponent name="suggest" class=&qu ...

  6. PHP exec/system启动windows应用程序,执行.bat批处理,执行cmd命令

    exec 或者 system 都可以调用cmd 的命令 直接上代码: <?php /** 打开windows的计算器 */ exec('start C:WindowsSystem32calc.e ...

  7. opencv常见代码

    http://blog.csdn.net/lyc_daniel/article/details/16883707

  8. jstl core 库 之 out set remove

    jstl 核心库 out标签 out:输出的标签 * value :输出的值 * default :默认值 * escapeXml :是否转移 默认为true(转义) 代码: <!-- 输出常量 ...

  9. [Linux]使用PHP编写Gearman的Worker守护进程

    在我之前的文章中,介绍过Gearman的使用.在我的项目中,我使用了PHP来编写一直运行的Worker.如果按照Gearman官方推荐的例子,只是简单的一个循环来等待任务,会有一些问题,包括:1.当代 ...

  10. 将csv文件读入数据库

      USE LHJTest create table #temp6//创建临时表 ( A nvarchar(max) NOT NULL, B nvarchar(max), C nvarchar(max ...