DFS搜索之选数问题

P1036 [NOIP2002 普及组] 选数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思考

我的第一种思考是先用排序搜索搜到所有的情况,再在所有情况中找到符合条件的统计次数,但是忽略了这样会导致重复选择的问题,这道题的核心是选择而不是排序。

看了大佬的题解后感觉不讲原则来求这种选择的题很微妙,很有趣

接下来我就按照我的理解来解释不降原则吧

先看代码

#include <iostream>
#include <cmath>
using namespace std;

int n, k;
int a[25], vis[25];
int cnt = 0;

bool check(int x) {
    if (x < 2)
        return false;
    for (int i = 2; i <= sqrt(x); i++) {
        if (x % i == 0)
            return false;
    }
    return true;
}

void dfs(int d, int sum, int stat) {
    if (d == k) {
        if (check(sum))
            cnt++;
        return;
    }

    for (int i = stat; i < n; i++) {
      dfs(d+1,sum+a[i],i+1);
    }
    return ;
}

int main() {
    cin >> n >> k;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    dfs(0, 0, 0);
    cout << cnt;
    return 0;
}

其中dfs用到了递增原则,原理差不多

例如5个数 

1,   2   , 3,4,  5;

所有的情况

选五个        1,2,3,4,5

选四个        1,2,3,4  1,2,3,5 1,3,4,5        2,3,4,5

选三个        1,2,3        1,2,4        1,2,5        1,3,4        1,3,5        1,4,5

                   2,3,4        2,3,5        2,4,5      

                   3,4,5

选两个        1,2        1,3        1,4        1,5

                   2,3        2,4        2,5      

                   3,4        3,5

                   4,5

选一个         1

                    2

                    3

                    4

                    5

上述的所有情况都会在遍历的时候经历到;

关键的是,这里面选择的情况(选择的数字)没有相同的,而且涉及到所有的情况,即具有全面性和特异性;

为了更好的理解,我将建立一个三角形,来理解这些情况是怎么出现的;

还是以上面五个数字为例

1        2        3        4        5

          2        3        4        5

                     3        4        5

                               4        5

                                         5

第一层dfs star=0

此时

1        2        3        4        5

都可以作为开始

因为下一层的dfs(d+1,sum+a[i],i+1);

i+1很关键

意味着下一层的dfs将会从它的下一位开始,即不会下降,满足的递增原则

画图理解

1        2        3        4        5        

          2        3        4        5        什么也不选

                     3        4        5        什么也不选

                               4        5        什么也不选

                                         5        什么也不选

    从第一层选一个数,下一个只能斜着选择,而且最右边是什么也不选

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zzcat.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值