DFS and Permutation and Combination (Description in C Language)#1

Use DFS to find the combination

Let’s look at the topic first:
Permutation and combination are commonly used mathematical methods. Combination is to extract r elements from n elements (without order and r≤n). We can simply understand n elements as natural numbers 1, 2, …, n, take any number of r from them.

You are now required to output all combinations.

For example, n=5,r=3n=5,r=3, all combinations are:
123,124,125,134,135,145,234,235,245,345;
solve the problem again: recursive DFS without backtracking

#include<stdio.h>
int n=0,r=0;
int a[25],b[20000];
int i=0,j=0,k=0,t=0,t1=0,t2=0;
void dfs(int i,int k)
{
    
    
if(i==n+1)
return;
i++;
//printf("i:%d t:%d k:%d\n",i,t,k);//用于检验
if(k==r)//位数达到时输出且返回上层
{
    
    for(j=0;j<r;j++)
{
    
    printf("%3d",a[j]);}
printf("\n");
return;
}
a[k]=i;//存入数组
dfs(i,k+1);//选入,此处i不必加入参数
dfs(i,k);//不选

}
int main()
{
    
    
scanf("%d %d",&n,&r);
dfs(0,0);
return 0;
}

Principle:
n<21 gives a lot of operating space.
With DFS recursion, each number has two choices: select the combination or not;
Insert picture description here
the advantage of this method is that there is no backtracking problem, and the disadvantage is that it is time-consuming. As can be seen from the figure, this method actually gives the possibility of different combinations of x digits, even if one is not selected, it is included in the end. Starting from the first digit, there are two possibilities for no digit. Regardless of the number of digits, the time complexity should be 2^n. You can use it with confidence when n<21 (and don’t worry about the order issue).
To give a counter example. From a
Insert picture description here
certain point of view, this problem can still be solved by a combination method (the number of n is a combination of 2)

int abss(long long g,long long h)
{
    
    if(g>=h)
return g-h;
    else
        return h-g;
}
void dfs(long long i,long long k)
{
    
    if(i>n)
        return;
    i++;
    //printf("i:%lld k:%lld\n",i,k);
    if(k==2)
    {
    
    
        j=abss(b[1],b[0]);
        //printf("%lld %lld\n",b[0],b[1]);
        if(j==c)
            sum++;

        return;
    }
    b[k]=a[i];
    dfs(i,k+1);
    dfs(i,k);
}

After modifying the conditions, the version is submitted to the TL in the three tests.
Therefore, this method is easy to directly kill when the amount of data is large,
including the backpack problem. If we can list all possible combinations, the natural problem will be solved, but due to time constraints, it does not allow much It can only be DP, or use DFS with backtracking .
The arrangement problem is the same, and it needs to bring backtracking DFS .
(Two sample questions are from Luogu.)

Guess you like

Origin blog.csdn.net/weixin_43736127/article/details/105563197