zoukankan      html  css  js  c++  java
  • 【做题笔记】P1025数的划分

    可以说是这个题的一个变种,然而直接成了黄题是什么鬼(((

    注:上面那篇blog里对于 dfs 的讲解不是很到位,所以这次就当是修一下锅www/wq


    首先,我们发现这个玩意和 dfs 的搞法一毛一样,所以果断考虑 dfs !

    如果直接去遍历所有的状态,不仅耗时,而且难以辨别重复。

    那么我们发现,按照题目的要求,也就是让我们找到有多少个本质不同的组合(即构成组合的数字不同)。

    那么我们发现:在一种本质相同的组合中,一定有一种组合保证升序排列

    例如:我们现在要把 10 分成 5 份,那么对于一种本质相同的排列:

    2 1 7
    2 7 1
    7 2 1
    7 1 2
    1 2 7 //升序
    ......
    

    那么这个本质相同的组合中升序排列就是1 2 7这一种。

    由于我们只需要知道有所少个本质不同的组合,所以我们只要找到一个本质相同的组合中升序排列的组合即可!

    构造

    如何构造一组升序排列?

    如果我们在递归的过程中记录一个 start 参数表示我们在上一层递归中选的数,那么只要任选一个 (i) ,使得 (startleq i) 即可(注意到可以不是单调递增的,i.e. 允许构造出的序列存在重复值)!

    那么只要遍历所有的 (i(startleq i leq n)) ,然后递归即可。

    参考代码(60分):

    #include <cstdio> 
    #include <algorithm>
    
    int n, k, ans;
    
    void dfs(int start, int num, int x) {
    //num表示当前的序列之和,x表示当前有x个数在序列里
        if(x==k) { 
            if(num==n)
                ++ans;
            return ; 
        } 
        for(int i=start;i<=n;i++) 
            dfs(i, num+i, x+1);
    } 
    
    int main(void) {
        scanf("%d%d", &n, &k);
    
        dfs(1, 0, 0);
    
        printf("%d
    ", ans);
    
        return 0;
    }
    

    剪枝

    考虑如何通过剪枝优化。

    剪枝的核心思想是排除当前和当前之后根本没有可能满足条件的解。那么我们发现,若当前序列中的元素总和 (x) 加上现在尝试的 (i) 已经大于我们要拆分的 (n) 了,那么就可以果断退出(因为后面的 (i) 是越来越大的)!

    于是有AC代码:

    #include <cstdio> 
    #include <algorithm>
    
    int n, k, ans;
    
    void dfs(int start, int num, int x) {
        if(x==k) { 
            if(num==n)
                ++ans;
            return ; 
        } 
        for(int i=start;num+i<=n;i++) 
            dfs(i, num+i, x+1);
    } 
    
    int main(void) {
        scanf("%d%d", &n, &k);
    
        dfs(1, 0, 0);
    
        printf("%d
    ", ans);
    
        return 0;
    }
    
  • 相关阅读:
    Windows JScript 在 游览器 中运行 调试 Shell 文件系统
    autohotkey 符号链接 软连接 symbolink
    软链接 硬链接 测试
    SolidWorks 修改 基准面 标准坐标系
    手机 路径 WebDAV 映射 驱动器
    Win10上手机路径
    explorer 命令行
    单位公司 网络 封锁 屏蔽 深信 AC
    cobbler自动化部署原理篇
    Docker四种网络模式
  • 原文地址:https://www.cnblogs.com/BlueInRed/p/12617587.html
Copyright © 2011-2022 走看看