zoukankan      html  css  js  c++  java
  • ybt1317 组合方案(dfs经典例题)超硬核

    ybt1317 组合输出

    dfs(深搜)例题

    【题目描述】

    排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。

    现要求你用递归的方法输出所有组合。

    例如n=5,r=3,所有组合为:

    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
    

    【输入】

    一行两个自然数n、r(1<n<21,1≤r≤n)。

    【输出】

    所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。

    【输入样例】

    5 3
    

    【输出样例】

      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<=r<n<21,根据组合公式:

    [C^r_n=frac {n!}{r!(n-r)!} ]

    可知,如果n取最大值20,那么方案数将是:

    [frac {2432902008176640000}{r!(20-r)!} ]

    画出图像后,发现图像过r=10对称,r=10时取到最大值184756。

    每个方案会有最多19个元素,共有19*184756=3510364个元素。

    dfs的复杂度为大约O(3.5*10^6^),可以接受。

    我一开始的代码出了许多问题,经过我的辛苦努力,最后还是AC了,看来想算法远不如实现算法困难:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,r,ans[30];
    void dfs(int at,int x) {//at表示当前要判断的位,x表示上一位的数字(这一位的数字要从x之后找)
    	for(int i=x+1;i<=n;i++) {//枚举at位所有可行的数字
    		ans[at]=i;//赋值
    		if(at==r) {//位数已经足够,可以输出
    			for(int j=1;j<=r;j++){
    				printf("%3d",ans[j]);//格式
    			}
    			cout<<endl; 
    		}
    		else{
    			dfs(at+1,i);//当前位不是最后一位,继续dfs,以i为当前位,也就是at+1位的上一位
    		}
    	}
    	return;
    }
    int main() {
    	cin>>n>>r;
    	dfs(1,0);//共同的起点:当前位是第1位,上一位(第零位)值是0
    	return 0;
    }
    

    (本来调试时把第10行printf里的ans[j]打成ans[i],并且把第22行的dfs(1,0)打成dfs(0,0),样例过不了吓得我认为自己连例题都要借鉴题解)

    但是我终于自己打出来此题,祝贺一下!!

  • 相关阅读:
    September 29th 2017 Week 39th Friday
    September 28th 2017 Week 39th Thursday
    September 27th 2017 Week 39th Wednesday
    September 26th 2017 Week 39th Tuesday
    September 25th 2017 Week 39th Monday
    September 24th 2017 Week 39th Sunday
    angular2 学习笔记 ( Form 表单 )
    angular2 学习笔记 ( Component 组件)
    angular2 学习笔记 ( Http 请求)
    angular2 学习笔记 ( Router 路由 )
  • 原文地址:https://www.cnblogs.com/Wild-Donkey/p/12234332.html
Copyright © 2011-2022 走看看