(dfs)选数

题目

从 1,2,3,⋯,30 这 30 个数中选 8 个数出来,使得和值为 200。问有多少种选法。
输出70.

思路

可行性剪枝:
要么选要么不选,如果选的多,退出,和超过200退出,选到最后一个数,进行判断,满足条件ans+1.

重复性剪枝:
选出来的数的位置是递增的,用一个参数来记录上一次选取的数的位置,此次选择从这个数之后开始选取,最后选出来的方案不会重复

代码

#include <iostream>
using namespace std;
int n, k, sum, ans;
int a[40];
void dfs(int i, int cnt, int s) {
    if(cnt>k){
        return ;
    }
    if(s>sum){
        return ;
    }
    if (i == n) {
        if (cnt == k && s == sum) {
            ans++;
        }
        return;
    }
    dfs(i + 1, cnt, s);
    dfs(i + 1, cnt + 1, s + a[i]);
}
int main() {
    n = 30;
    k = 8;
    sum = 200;
    for (int i = 0; i < 30; i++) {
        a[i] = i + 1;
    }
    ans = 0;
    dfs(0, 0, 0);
    cout << ans << endl;
    return 0;
}
#include <iostream>
using namespace std;
int n, k, sum, ans;
int a[40];
bool xuan[40];
void dfs(int s, int cnt,int pos) {
    if(s>sum||cnt>k){
		return ;
    }
    if (s == sum && cnt == k) {
        ans++;
    }
    for (int i = pos; i < n; i++) {
        if (!xuan[i]) {
            xuan[i] = 1;
            dfs(s + a[i], cnt + 1,i+1);
            xuan[i] = 0;
        }
    }
}
int main() {
    n = 30;
    k = 8;
    sum = 200;
    for (int i = 0; i < 30; i++) {
        a[i] = i + 1;
    }
    ans = 0;
    dfs(0, 0,0);
    cout << ans << endl;
    return 0;
}
发布了218 篇原创文章 · 获赞 131 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_40828914/article/details/95902108