• Anya and Cubes


    题目:

    给你n个数,n≤26 初始序列为ai​,1≤ai≤1e9
    你有k个! ,每个!可以使序列中的一个数变成ai!(k不一定要用完)
    例如5!=120
    求:选出任意个数使他们和的等于S的方案数(0≤S≤1e16)
    思路:

    三种情况深度遍历,贴变阶乘,不贴取原值,不贴不取,把n分一半左右分别遍历;

    dfs1当used贴纸数大于k返回;当左区间越过右区间返回;

    dfs2当used贴纸数大于k返回;当当前总和大于所有总和返回;当左区间越过右区间,取所有可能使总和-已有和的可能,返回。

    20的阶乘大于1e16,所以在阶乘判断时a[i]小于20。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include <bitset>
     8 #include<set>
     9 #include<map>
    10 #include<unordered_map>
    11 #include<vector>
    12 #include<cmath>
    13 #include<string>
    14 using namespace std;
    15 const int N = 30;
    16 unordered_map<long long, long long>M[N];
    17 long long fact[N];
    18 int n, k, a[N];
    19 long long s, ans;
    20 void dfs1(int now, int end, long long S, int used) {
    21   //  cout << "dfs1(" << now << "," << end << "," << S << "," << used << ")" << endl;
    22     if (used > k)
    23         return;
    24     if (now > end) {
    25         M[used][S] ++;
    26   //      cout << "M[" << used << "][" << S << "]" << "=" << M[used][S] << endl;
    27         return;
    28     }
    29     dfs1(now + 1, end, S, used);
    30     dfs1(now + 1, end, S + a[now], used);
    31     if (a[now] <= 20)
    32         dfs1(now + 1, end, S + fact[a[now]], used + 1);
    33 }
    34 
    35 void dfs2(int now, int end, long long S, int used) {
    36   //  cout << "dfs1(" << now << "," << end << "," << S << "," << used << ")" << endl;
    37     if (used > k)
    38         return;
    39     if (S > s)
    40         return;
    41     if (now > end) {
    42         for (int i = 0; i <= k - used; i++) {
    43             ans += M[i][s - S];
    44  //           cout << "ans+=" << M[i][s - S] << " " << "ans=" << ans << endl;
    45         }
    46         return;
    47     }
    48     dfs2(now + 1, end, S, used);
    49     dfs2(now + 1, end, S + a[now], used);
    50     if (a[now] <= 20)
    51         dfs2(now + 1, end, S + fact[a[now]], used + 1);
    52 }
    53 int main() {
    54     cin >> n >> k >> s;
    55     fact[1] = 1;
    56     for (int i = 2; i <= 20; i++)
    57         fact[i] = fact[i - 1] * i;
    58     for (int i = 1; i <= n; i++)
    59         cin >> a[i];
    60     dfs1(1, (n + 1) / 2, 0, 0);
    61     cout << endl << endl;
    62     dfs2((n + 1) / 2 + 1, n, 0, 0);
    63     cout << ans << endl;
    64     return 0;
    65 }

    链接:https://www.luogu.com.cn/problem/solution/CF525E

  • 相关阅读:
    LeetCode-079-单词搜索
    awk学习笔记
    Python实现排列组合算法
    python模拟登录人人
    Python的SQLite数据库使用方法
    C语言排序算法——插入排序算法
    C语言排序算法——简单选择排序算法
    C语言排序算法——冒泡排序算法
    Python学习——python的函数参数传递
    Python学习——实现secure copy功能
  • 原文地址:https://www.cnblogs.com/0211ji/p/13343846.html
Copyright © 2020-2023  润新知