算法后十五道题答案_自用

//
// Created by 10986 on 2023/9/20.
//
#include<bits/stdc++.h>
using namespace std;
class base_t {
public:
    virtual void process() {};

    virtual void printScreen() {};
};
void iteratorFun_t(base_t *b) {
    b->process();
    b->printScreen();
}

//[算法课回溯]组合问题
class myAlgorithm_13 : public base_t {
public:
    myAlgorithm_13() {
        scanf("%d", &n);
        scanf("%d", &k);

    }

    void process() override {
        dfs({}, 0);
    }

    void printScreen() override {
        cout << "[";
        for (int i = 0; i < vec.size() - 1; i++) {
            cout << "[";
            for (int j = 0; j < vec[i].size() - 1; j++) {
                cout << vec[i][j] << ", ";
            }
            cout << vec[i][vec[i].size() - 1] << "], ";
        }
        cout << "[";
        for (int j = 0; j < vec[vec.size() - 1].size() - 1; j++) {
            cout << vec[vec.size() - 1][j] << ", ";
        }
        cout << vec[vec.size() - 1][vec[vec.size() - 1].size() - 1] << "]]";
    }

private:
    int n, k;
    vector<vector<int>> vec;

    void dfs(vector<int> vec1, int number) {
        if (vec1.size() >= k) {
            vec.push_back(vec1);
            return;
        }
        for (int i = number + 1; i <= n; i++) {
            vector<int> temp = vec1;
            temp.push_back(i);
            dfs(temp, i);
        }
    }
};
//[算法课回溯]找出所有子集的异或总和再求和
class myAlgorithm_14 : public base_t {
public:
    myAlgorithm_14() {
        res = 0;
        int value;
        while (cin >> value)
            vec.push_back(value);
    }

    void process() override {
        subsetXORSum(vec);
    }

    void printScreen() override {
        cout << res;
    }

private:
    int res;
    int n;
    vector<int> vec;

    int subsetXORSum(vector<int> &nums) {
        res = 0;
        int n = nums.size();
        for (int i = 0; i < (1 << n); ++i) {   // 遍历所有子集
            int tmp = 0;
            for (int j = 0; j < n; ++j) {   // 遍历每个元素
                if (i & (1 << j)) {
                    tmp ^= nums[j];
                }
            }
            res += tmp;
        }
        return res;
    }

};
//[算法课回溯]分割回文串
class myAlgorithm_15 : public base_t {
public:
    myAlgorithm_15() {
        cin >> str;
    }

    void process() override {
        ret = partition(str);
    }

    void printScreen() override {
        cout << "[";
        for (int i = 0; i < ret.size() - 1; i++) {
            cout << "[";
            for (int j = 0; j < ret[i].size() - 1; j++) {
                cout << ret[i][j] << ", ";
            }
            cout << ret[i][ret[i].size() - 1];
            cout << "], ";
        }
        cout << "[";
        int i = ret.size() - 1;
        for (int j = 0; j < ret[i].size() - 1; j++) {
            cout << ret[i][j] << ", ";
        }
        cout << ret[i][ret[i].size() - 1];
        cout << "]]";
    }

private:
    string str;
    vector<vector<int>> f;
    vector<vector<string>> ret;
    vector<string> ans;
    int n;


    void dfs(const string &s, int i) {
        if (i == n) {
            ret.push_back(ans);
            return;
        }
        for (int j = i; j < n; ++j) {
            if (f[i][j]) {
                ans.push_back(s.substr(i, j - i + 1));
                dfs(s, j + 1);
                ans.pop_back();
            }
        }
    }

    vector<vector<string>> partition(string s) {
        n = s.size();
        f.assign(n, vector<int>(n, true));

        for (int i = n - 1; i >= 0; --i) {
            for (int j = i + 1; j < n; ++j) {
                f[i][j] = (s[i] == s[j]) && f[i + 1][j - 1];
            }
        }

        dfs(s, 0);
        return ret;
    }

};
//[算法课回溯]目标和
class myAlgorithm_16 : public base_t {
public:
    myAlgorithm_16() {
        int value;
        while (cin >> value)
            vec.push_back(value);
        target = value;
        vec.pop_back();
    }

    void process() override {
        res = findTargetSumWays(vec, target);
    }

    void printScreen() override {
        cout << res;
    }

private:
    int res;
    vector<int> vec;
    int target;

    int findTargetSumWays(vector<int> &nums, int target) {
        int sum = 0;
        for (int &num: nums) {
            sum += num;
        }
        int diff = sum - target;
        if (diff < 0 || diff % 2 != 0) {
            return 0;
        }
        int n = nums.size(), neg = diff / 2;
        vector<vector<int>> dp(n + 1, vector<int>(neg + 1));
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++) {
            int num = nums[i - 1];
            for (int j = 0; j <= neg; j++) {
                dp[i][j] = dp[i - 1][j];
                if (j >= num) {
                    dp[i][j] += dp[i - 1][j - num];
                }
            }
        }
        return dp[n][neg];
    }
};


//[算法课分支限界法]组合
class myAlgorithm_17 : public base_t {
public:
    myAlgorithm_17() {
        int value;
        while (cin >> value)
            vec.push_back(value);
        k = value;
        vec.pop_back();
    }

    void process() override {
        combine(vec[0], k);
    }

    void printScreen() override {
        for (int i = 0; i < ans.size(); i++) {
            for (int j = 0; j < ans[i].size() - 1; j++) {
                cout << ans[i][j] << " ";
            }
            cout << ans[i][ans[i].size() - 1] << endl;

        }
    }

private:
    vector<int> vec;
    int k;

    vector<int> temp;
    vector<vector<int>> ans;

    void dfs(int cur, int n, int k) {
        // 剪枝:temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 temp
        if (temp.size() + (n - cur + 1) < k) {
            return;
        }
        // 记录合法的答案
        if (temp.size() == k) {
            ans.push_back(temp);
            return;
        }
        // 考虑选择当前位置
        temp.push_back(cur);
        dfs(cur + 1, n, k);
        temp.pop_back();
        // 考虑不选择当前位置
        dfs(cur + 1, n, k);
    }

    vector<vector<int>> combine(int n, int k) {
        dfs(1, n, k);
        return ans;
    }

};
//[算法课分支限界法]大礼包
class myAlgorithm_18 : public base_t {
public:
    myAlgorithm_18() {
        int data, n;
        res = 0;
        vector<int> temp;
        string str;
        getline(cin, str);

        stringstream input(str);
        string temp1;
        while (getline(input, temp1, ' ')) {
            n = atoi(temp1.c_str());
            price.push_back(n);
        }

        price.pop_back();

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < price.size() + 1; j++) {
                scanf("%d", &data);
                temp.push_back(data);
            }
            special.push_back(temp);
            temp = {};
        }


        for (int i = 0; i < price.size(); i++) {
            scanf("%d", &data);
            needs.push_back(data);
        }


    }

    void process() override {

        res = shoppingOffers(price, special, needs);
    }

    void printScreen() override {
        cout << res;
    }

private:
    vector<int> price;
    vector<vector<int>> special;
    vector<int> needs;
    map<vector<int>, int> memo;
    int res;

    int shoppingOffers(vector<int> &price, vector<vector<int>> &special, vector<int> &needs) {
        int n = price.size();
        // 过滤不需要计算的大礼包,只保留需要计算的大礼包
        vector<vector<int>> filterSpecial;
        for (auto &sp: special) {
            int totalCount = 0, totalPrice = 0;
            for (int i = 0; i < n; ++i) {
                totalCount += sp[i];
                totalPrice += sp[i] * price[i];
            }
            if (totalCount > 0 && totalPrice > sp[n]) {
                filterSpecial.emplace_back(sp);
            }
        }

        return dfs(price, special, needs, filterSpecial, n);
    }

    // 记忆化搜索计算满足购物清单所需花费的最低价格
    int
    dfs(vector<int> price, const vector<vector<int>> &special, vector<int> curNeeds, vector<vector<int>> &filterSpecial,
        int n) {
        if (!memo.count(curNeeds)) {
            int minPrice = 0;
            for (int i = 0; i < n; ++i) {
                minPrice += curNeeds[i] * price[i]; // 不购买任何大礼包,原价购买购物清单中的所有物品
            }
            for (auto &curSpecial: filterSpecial) {
                int specialPrice = curSpecial[n];
                vector<int> nxtNeeds;
                for (int i = 0; i < n; ++i) {
                    if (curSpecial[i] > curNeeds[i]) { // 不能购买超出购物清单指定数量的物品
                        break;
                    }
                    nxtNeeds.emplace_back(curNeeds[i] - curSpecial[i]);
                }
                if (nxtNeeds.size() == n) { // 大礼包可以购买
                    minPrice = min(minPrice, dfs(price, special, nxtNeeds, filterSpecial, n) + specialPrice);
                }
            }
            memo[curNeeds] = minPrice;
        }
        return memo[curNeeds];
    }

};
//[算法课分支限界法]Partition to K Equal Sum Subsets
class myAlgorithm_19 : public base_t {
public:
    myAlgorithm_19() {
        int data;
        while (cin >> data) {
            vec.push_back(data);
        }
        k = data;
        vec.pop_back();
        res = 0;
    }

    void process() override {
        res = canPartitionKSubsets(vec, k);
    }

    void printScreen() override {
        if (res) {
            cout << "true";
        } else {
            cout << "false";
        }
    }

private:
    vector<int> vec;
    int k;
    int res;

    bool canPartitionKSubsets(vector<int> &nums, int k) {
        int all = accumulate(nums.begin(), nums.end(), 0);
        if (all % k > 0) {
            return false;
        }
        int per = all / k;
        sort(nums.begin(), nums.end());
        if (nums.back() > per) {
            return false;
        }
        int n = nums.size();
        vector<bool> dp(1 << n, true);
        function<bool(int, int)> dfs = [&](int s, int p) -> bool {
            if (s == 0) {
                return true;
            }
            if (!dp[s]) {
                return dp[s];
            }
            dp[s] = false;
            for (int i = 0; i < n; i++) {
                if (nums[i] + p > per) {
                    break;
                }
                if ((s >> i) & 1) {
                    if (dfs(s ^ (1 << i), (p + nums[i]) % per)) {
                        return true;
                    }
                }
            }
            return false;
        };
        return dfs((1 << n) - 1, 0);
    }
};
//[算法课分支限界法]分割等和子集
class myAlgorithm_20 : public base_t {
public:
    myAlgorithm_20() {
        int data = 0;
        while (cin >> data) {
            vec.push_back(data);
        }
        res = 0;
    }

    void process() override {
        res = canPartition(vec);
    }

    void printScreen() override {
        if (res) {
            cout << "true";
        } else {
            cout << "false";
        }
    }

private:
    vector<int> vec;
    int res;

    bool canPartition(vector<int> &nums) {
        int n = nums.size();
        if (n < 2) {
            return false;
        }
        int sum = accumulate(nums.begin(), nums.end(), 0);
        int maxNum = *max_element(nums.begin(), nums.end());
        if (sum & 1) {
            return false;
        }
        int target = sum / 2;
        if (maxNum > target) {
            return false;
        }
        vector<vector<int>> dp(n, vector<int>(target + 1, 0));
        for (int i = 0; i < n; i++) {
            dp[i][0] = true;
        }
        dp[0][nums[0]] = true;
        for (int i = 1; i < n; i++) {
            int num = nums[i];
            for (int j = 1; j <= target; j++) {
                if (j >= num) {
                    dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num];
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        return dp[n - 1][target];
    }

};
//[算法课分支限界法]硬币问题
class myAlgorithm_21 : public base_t {
public:
    myAlgorithm_21() {
        int data;
        scanf("%d", &data);
        target = data;
        while (cin >> data)
            vec.push_back(data);

    }

    void process() override {
        res = bfs(target, vec.size() - 1);
    }

    void printScreen() override {
        cout << res;
    }

private:
    int res;
    int target;
    vector<int> vec;

    int bfs(int surplus, int index) {
        if (index < 0 || surplus < 0)
            return 0;
        if (surplus == 0)
            return 1;
        int number = 0;
        for (int i = index; i >= 0; i--) {
            number += bfs(surplus - vec[i], i);
        }
        return number;
    }
};


//[算法课动态规划] 打家劫舍
class myAlgorithm_22 : public base_t {
public:
    myAlgorithm_22() {
        int data;
        while (cin >> data)
            vec.push_back(data);
    }

    void process() override {
        res = rob(vec);
    }

    void printScreen() override {
        cout << res;
    }

private:
    vector<int> vec;
    int res;

    int rob(vector<int> &nums) {
        if (nums.empty()) {
            return 0;
        }
        int size = nums.size();
        if (size == 1) {
            return nums[0];
        }
        vector<int> dp = vector<int>(size, 0);
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < size; i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[size - 1];
    }

};
//[算法课动态规划] 戳气球
class myAlgorithm_23 : public base_t {
public:
    myAlgorithm_23() {
        int data;
        while (cin >> data)
            vec.push_back(data);
    }

    void process() override {
        res = maxCoins(vec);
    }

    void printScreen() override {
        cout << res;
    }

private:
    int res;
    vector<int> vec;
    vector<vector<int>> rec;
    vector<int> val;

    int solve(int left, int right) {
        if (left >= right - 1) {
            return 0;
        }
        if (rec[left][right] != -1) {
            return rec[left][right];
        }
        for (int i = left + 1; i < right; i++) {
            int sum = val[left] * val[i] * val[right];
            sum += solve(left, i) + solve(i, right);
            rec[left][right] = max(rec[left][right], sum);
        }
        return rec[left][right];
    }

    int maxCoins(vector<int> &nums) {
        int n = nums.size();
        val.resize(n + 2);
        for (int i = 1; i <= n; i++) {
            val[i] = nums[i - 1];
        }
        val[0] = val[n + 1] = 1;
        rec.resize(n + 2, vector<int>(n + 2, -1));
        return solve(0, n + 1);
    }

};
//[算法课动态规划] 摆动序列
class myAlgorithm_26 : public base_t {
public:
    myAlgorithm_26() {
        int data;
        while (cin >> data)
            vec.push_back(data);
    }

    void process() override {
        res = wiggleMaxLength(vec);
    }

    void printScreen() override {
        cout << res;
    }

private:
    vector<int> vec;
    int res;

    int wiggleMaxLength(vector<int> &nums) {
        int n = nums.size();
        if (n < 2) {
            return n;
        }
        vector<int> up(n), down(n);
        up[0] = down[0] = 1;
        for (int i = 1; i < n; i++) {
            if (nums[i] > nums[i - 1]) {
                up[i] = max(up[i - 1], down[i - 1] + 1);
                down[i] = down[i - 1];
            } else if (nums[i] < nums[i - 1]) {
                up[i] = up[i - 1];
                down[i] = max(up[i - 1] + 1, down[i - 1]);
            } else {
                up[i] = up[i - 1];
                down[i] = down[i - 1];
            }
        }
        return max(up[n - 1], down[n - 1]);
    }

};


//[算法课贪心] 分发糖果
class myAlgorithm_24 : public base_t {
public:
    myAlgorithm_24() {
        int data;
        while (cin >> data)
            vec.push_back(data);
    }

    void process() override {
        res = candy(vec);
    }

    void printScreen() override {
        cout << res;
    }

private:
    vector<int> vec;
    int res;

    int candy(vector<int> &ratings) {
        int n = ratings.size();
        vector<int> left(n);
        for (int i = 0; i < n; i++) {
            if (i > 0 && ratings[i] > ratings[i - 1]) {
                left[i] = left[i - 1] + 1;
            } else {
                left[i] = 1;
            }
        }
        int right = 0, ret = 0;
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1 && ratings[i] > ratings[i + 1]) {
                right++;
            } else {
                right = 1;
            }
            ret += max(left[i], right);
        }
        return ret;
    }

};
//[算法课深度优先搜索] 水壶问题
class myAlgorithm_25 : public base_t {
public:
    myAlgorithm_25() {
        int data;
        while (cin >> data)
            vec.push_back(data);
    }

    void process() override {
        res = canMeasureWater(vec[0], vec[1], vec[2]);

    }

    void printScreen() override {
        if (res) {
            cout << "true";
        } else {
            cout << "false";
        }
    }

private:
    int res;
    vector<int> vec;

    bool canMeasureWater(int x, int y, int z) {
        using PII = pair<int, int>;
        stack<PII> stk;
        stk.emplace(0, 0);
        auto hash_function = [](const PII &o) { return hash<int>()(o.first) ^ hash<int>()(o.second); };
        unordered_set<PII, decltype(hash_function)> seen(0, hash_function);
        while (!stk.empty()) {
            if (seen.count(stk.top())) {
                stk.pop();
                continue;
            }
            seen.emplace(stk.top());

            auto [remain_x, remain_y] = stk.top();
            stk.pop();
            if (remain_x == z || remain_y == z || remain_x + remain_y == z) {
                return true;
            }
            // 把 X 壶灌满。
            stk.emplace(x, remain_y);
            // 把 Y 壶灌满。
            stk.emplace(remain_x, y);
            // 把 X 壶倒空。
            stk.emplace(0, remain_y);
            // 把 Y 壶倒空。
            stk.emplace(remain_x, 0);
            // 把 X 壶的水灌进 Y 壶,直至灌满或倒空。
            stk.emplace(remain_x - min(remain_x, y - remain_y), remain_y + min(remain_x, y - remain_y));
            // 把 Y 壶的水灌进 X 壶,直至灌满或倒空。
            stk.emplace(remain_x + min(remain_y, x - remain_x), remain_y - min(remain_y, x - remain_x));
        }
        return false;
    }
};
//[算法课滑动窗口] 最长不重复子串
class myAlgorithm_27 : public base_t {
public:
    myAlgorithm_27() {
        getline(cin, str);
        res = 0;
    }

    void process() override {
        res = lengthOfLongestSubstring(str);
    }

    void printScreen() override {
        cout << res << endl;
    }

private:
    string str;
    int res;

    int lengthOfLongestSubstring(string s) {

        int s_size = s.size();
        int left = 0;
        int answer = 0;
        unordered_set<char> st;

        for (int right = 0; right < s_size; ++right) {
            while (st.find(s[right]) != st.end()) {
                st.erase(s[left]);
                ++left;
            }
            st.insert(s[right]);
            answer = max(answer, right - left + 1);
        }

        return answer;
    }


};

int main() {
//    myAlgorithm_13 my;
//    myAlgorithm_14 my;
//    myAlgorithm_15 my;
//    myAlgorithm_16 my;
//    myAlgorithm_17 my;
//    myAlgorithm_18 my;
//    myAlgorithm_19 my;
//    myAlgorithm_20 my;
//    myAlgorithm_21 my;
//    myAlgorithm_22 my;
//    myAlgorithm_23 my;
//    myAlgorithm_24 my;
//    myAlgorithm_25 my;
//    myAlgorithm_26 my;
    myAlgorithm_27 my;


    iteratorFun_t(&my);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值