zoukankan      html  css  js  c++  java
  • 【算法•日更•第五期】深度优先搜索中的剪枝优化(二)例题:数的划分题解

      上一期我们讲到了剪枝是什么(附前一期链接:戳这里),那么我们今天就来实战模拟一下,废话不多说,直接上题:


    P1025 数的划分

    题目描述

    将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序)。

    例如:n=7k=3,下面三种分法被认为是相同的。

    1,1,5;
    1,5,1;
    5,1,1.

    问有多少种不同的分法。

    输入输出格式

    输入格式:

    n,k(6<n200,2k6)

    输出格式:

    11个整数,即不同的分法。

    输入输出样例

    输入样例#1:
    7 3
    
    输出样例#1: 
    4
    

    说明

    四种分法为:
    1,1,5;
    1,2,4;
    1,3,3;
    2,2,3.

      这道题一看就是一道搜索题,没有什么难度,但是路过的大佬你真的会优化这道搜索题吗?学就得学彻底。

      常规搜索讲解:

      前置技能:搜索

      搜索的方法很简单既然已经知道了数的个数,那么直接依次枚举每个位子上的值,然后判重即可。

      这道题的数据规模还算小,如果大一些了,那么它的时间复杂制度就会高到难以忍受。

      所以,我们就需要用到剪枝优化。

      剪枝优化讲解:

      这道题有两个用到剪枝的地方:

      ①我们为了避免重复,所以可以规定一个顺序,比如递增,即a[i-1]<=a[i]。比如说题中的例子:1,1,5和1,5,1和5,1,1中只取1,1,5。所以下一个数分配的最低值就是上一个数。

      ②因为上面定好了顺序,所以,我们总会发现这样的规律:剩下的n/剩下分的位数是下一个数分配的最高值,这是为什么呢?这个不好解释,举个栗子:假如好剩下12分到3个位子上去,那么第一个位子上绝对不会超过4,一旦超过就满足不了a[i-1]<=a[i]了。不信自己模拟一下。

      代码如下:

      

     1 #include<iostream>
     2 using namespace std;
     3 int n,k,a[10000],sum=0,ans;
     4 void dfs(int past,int cnt,int num)
     5 {
     6     if(cnt==1)
     7     {
     8         ans++;
     9         return;
    10     }
    11     for(int i=past;i<=num/cnt;i++)
    12     dfs(i,cnt-1,num-i);
    13 }
    14 int main()
    15 {
    16     cin>>n>>k;
    17     dfs(1,k,n);
    18     cout<<ans;
    19     return 0;
    20 }
  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    微信小程序TodoList
    C语言88案例-找出数列中的最大值和最小值
    C语言88案例-使用指针的指针输出字符串
  • 原文地址:https://www.cnblogs.com/TFLS-gzr/p/11150827.html
Copyright © 2011-2022 走看看