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

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

n<25

可以知道直接使用n去枚举自然受不了, 我们将n个数字分为两部分来算,前面n/2个数字 我们枚举他们使用j次可以得到的数,然后后面的n-n/2个数再次使用这个方法,直接在dfs枚举的时候进行判断S-s 在前一个钟是否出现过,出现过就加起来。 分块处理 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <map>
 5 #include<cstdio>
 6 using namespace std;
 7 typedef long long LL;
 8 map<LL,int>mp[30];
 9 LL A[30];
10 LL dp[30];
11 LL time[1000000];
12 int n,K;
13 LL S,ans;
14 void dfs(int p, int k, LL s){
15     if(p==n/2){
16          mp[k][s]++;
17     }else{
18         dfs(p+1,k,s);
19         if(s+A[p]<=S)dfs(p+1,k,s+A[p]);
20         if(k+1<=K && A[p]<=18 &&  s+dp[A[p]] <=S ) dfs(p+1,k+1,s+dp[A[p]]);
21     }
22 }
23 void dfs1(int p, int k, LL s){
24     if(p==n){
25          for(int i =0; i+k<=K; i++)
26             if(mp[i].count(S-s)>0) ans+=mp[i][S-s];
27     }else{
28          dfs1(p+1,k,s);
29          if(s+A[p]<=S) dfs1(p+1,k,s+A[p]);
30          if(k+1<=K && A[p]<=18 && s+dp[A[p]]<=S) dfs1(p+1,k+1,s+dp[A[p]]);
31     }
32 }
33 int main()
34 {
35 
36 
37    dp[0]=1;
38    for(LL i=1; i<=18; i++) dp[i]=dp[i-1]*i;
39    ans=0;
40    scanf("%d%d%I64d",&n,&K,&S);
41    for(int i=0; i<n; i++)
42       scanf("%I64d",&A[i]);
43    dfs(0,0,0);
44    dfs1(n/2,0,0);
45    printf("%I64d\n",ans);
46     return 0;
47 }

 

转载于:https://www.cnblogs.com/Opaser/p/4381974.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值