dfs中关于选数类的问题

dfs中关于选数类的问题:

有两种dfs:

以后面对这类问题要常采用第二种dfs,原因是,第一种相当于选数是所有的情况都是组合,第二种都是排列,

所以第二种更加全面,特别是与方向有关时,只能用第二种。

ps:

 

1.剪枝真的很重要,TLE就是这样阻止你成功的脚步的

注意理解这里的剪枝:

if (distance >= ans) //这里这个剪枝之所以能用,是因为dfs都是从左边开始一条路搜完之后才搜下一条路的,所以最左边的那条路搜完之后,就已经记录下来了一个ans

        return;

 

2.学会卡时时间常数:int fuck即可,一般数量级在“千万”左右

 

 

 

 

 


void dfs(int start, int depth, int s, int t)//s,t表示总的酸度,甜度

{

    if (depth >= 1)//这里是为了跳过一开始main函数中运行dfs时,一开始给出参数为s=1,t=0的影响

    {

        ans = min(abs(s - t), ans);//一步最小的也可以

    }

    //start为目前所选数(配料)的编号

    if(depth==n){       //这里要注意传进来以后,满足结束条件以后,要再做一次操作

        return ;

    }

    for(int i=start;i<=n;i++){

        dfs(i + 1, depth + 1, s*a[i], t+b[i]);//参数一加,或者参数一乘,就表示这次操作已经选完了

    }   //第一次也是在这里选完的

}

PART TWO:

void dfs(int depth, double distance, int x)

{           //x用来记录上一次到达的点的序号

    fuck++; //用来卡时间常数的变量,真心fuck~

    if (fuck > 30000000)

        return;

    /* if (depth >= 1)

    {

        ans = min(ans, distance);//这个ans是在所有的dfs里变化的,一步所到达的最小不要,必须到n步,所以舍去

       

    }  */

    if (distance >= ans) //这里这个剪枝之所以能用,是因为dfs都是从左边开始一条路搜完之后才搜下一条路的,所以最左边的那条路搜完之后,就已经记录下来了一个ans

        return;

    if (depth == n) //求满n时,才求出最短距离

    {

        ans = min(ans, distance);

        return;

    }

    for (int i = 1; i <= n; i++)

    { //!!!:这里i等于1和i等于start是不一样的效果!!!,手模一次~~~

        if (!vis[i])

        {

            vis[i] = 1;//这个标注的过程和dfs搜索时时同步的~~~

            dfs(depth + 1, distance + sqrt(abs((a[i] - a[x])) * abs((a[i] - a[x])) + abs((b[i] - b[x])) * abs((b[i] - b[x]))), i);

            vis[i] = 0;//

        }

    }

}

posted @ 2021-03-04 17:00  py佐料  阅读(96)  评论(0)    收藏  举报