HJ93 数组分组

HJ93 数组分组

dfs/dp

题目描述

输入int型数组,询问该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),能满足以上条件,输出true;不满足时输出false。
本题含有多组样例输入。
输入描述:
第一行是数据个数,第二行是输入的数据

输出描述:
返回true或者false

示例1

输入:
4
1 5 -5 1
3
3 5 8
输出:
true
false
说明:
第一个样例:
第一组:5 -5 1
第二组:1
第二个样例:由于3和5不能放在同一组,所以不存在一种分法。

解题思路

题目说了3的倍数和5的倍数必须放在不同集合,那就先把这部分数组摘出来,然后看剩下的部分能否分配成需要的结果。
这里可以用 dfs 或者 dp,对于要组成的目标和,每个元素要么参与要么不参与,只要有一种方案能达到目标就算成功。

参考代码

注意这里的 v.size() 和 n 含义不同、值不同、更新不同时。

#include <bits/stdc++.h>
using namespace std;

vector<int> v;

// 数组元素能否凑出 target 值
bool dfs(int i, int target) {
    if (target == 0) return true;
    if (i < 0) return false;
    return dfs(i-1, target - v[i])
        || dfs(i-1, target);
}

int main() {
    cin.sync_with_stdio(false);
    int n;
    while (cin >> n) {
        v.reserve(n); //
        v.resize(0); //
        int64_t sumall = 0;
        int64_t sum5 = 0; // 5
        int64_t sum3 = 0; // 3
        for (int i=0; i<n; i++) {
            int x;
            cin >> x;
            sumall += x;
            if ((x % 5) == 0) {
                sum5 += x;
            } else if ((x % 3) == 0) {
                sum3 += x;
            } else {
                v.push_back(x);
            }
        }
        if (sumall % 2) {
            cout << "false
";
            continue;
        }
//         printf("sum3=%ld, sum5=%ld, sumall=%ld
", sum3, sum5, sumall);
//         for (int x : v) cout << x << ' '; cout << endl;
        cout << (dfs(v.size() - 1, sumall / 2 - sum3) ? "true
" : "false
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhcpku/p/15255313.html