zoukankan      html  css  js  c++  java
  • 生成子集——幸运的袋子

    幸运的数字Online Judge
    一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。
    例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3,你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。
    现在让你编程计算一下你可以获得的多少种不同的幸运的袋子。

    上图即为剪枝后的部分解答树,每个结点即代表一个可能解,只有橙色节点为我们需要的解,例如最左边节点代表1 + 1 + 2 + 3 > 1 * 1 * 2 * 3。

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    void DFS(vector<int> &X, vector<int> &path, vector<int>::iterator start, int &result) {
        int sum = 0, product = 1;
        for(vector<int>::iterator iter = path.begin(); iter != path.end(); ++iter) {
            sum += *iter;
            product *= *iter;
        }
        if(sum > product) result++;
        if(!path.empty() && sum < product) return;
    
        for(vector<int>::iterator iter = start; iter != X.end(); ++iter) {
            if(iter != start && *iter == *(iter - 1)) continue;
            path.push_back(*iter);
            if(path.front() == 1)
                DFS(X, path, iter + 1, result);
            path.pop_back();
        }
    }
    
    int main() {
        int N;
        cin >> N;
        vector<int> X(N);
        for(int i = 0; i < N; i++) cin >> X[i];
    
        sort(X.begin(), X.end());
        int result = 0;
        vector<int> path;
        DFS(X, path, X.begin(), result);
        cout << result << endl;
        return 0;
    }
    

    上面的解题思想是正确的,但是效率不高,无法通过所有测试用例。下面是牛客上给出的一个解法,可通过所有测试用例。

    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    
    std::vector<int> nums;
    int n, nxt[1005];
    
    int DFS(int i, int sum, int product) {
        if(i >= n) return sum > product;
        if(nums[i] > 1 && sum < product) return 0;
        return DFS(i + 1, sum + nums[i], product * nums[i]) + DFS(nxt[i], sum, product); //选,不选
    }
    
    int solve() {
        memset(nxt, 0, sizeof(nxt));
        int p = n;
        for(int i = n - 1; i >= 0; i--) {
            if(i < n - 1 && nums[i + 1] > nums[i]) p = i + 1;
            nxt[i] = p;
        }
        return DFS(0, 0, 1);
    }
    
    int main() {
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            int x; scanf("%d", &x);
            nums.push_back(x);
        }
        sort(nums.begin(), nums.end());
        cout << solve() << endl;
    }
  • 相关阅读:
    实验一 网络侦查与网络扫描
    网络对抗作业一
    [BSidesCF 2020]Hurdles
    [BSidesCF 2019]Mixer
    安恒期末 admin
    C#编程:正则表达式验证身份证校验码-10
    分享1-3年经验的Java面试
    SpringMVC配置web.xml文件详解(列举常用的配置)
    Hibernate全套增删改查+分页
    Node.js连接mysql数据库方法
  • 原文地址:https://www.cnblogs.com/shuaihanhungry/p/5748943.html
Copyright © 2011-2022 走看看