zoukankan      html  css  js  c++  java
  • Codeforces 431C k-Tree(记忆化搜索)

    题目链接

    题目大意

      给无限深度一颗k叉树,每个最小子树的边的权值都是1~k,问有多少从根结点出发,路径和为n且最少一条边为d的路径。

    解题思路

      首先看到要取模就知道直接枚举出所有的情况肯定是不可取的。考虑一下,如果有一条路径可以到达n,那之前肯定有路径可以到达n-1、n-2...n-k,然后在前一个状态的基础上再往前推,就能推到0~k的状态,所以我们只要能得到0~k的状态,也能往后推出到达n的状态。如果不考虑d的话,这个还是很好写的,很显然用一个递归就能完成这个操作,而且用数组直接就可以存储到达某个状态的路径数量。
      考虑至少有一条路径为d的情况。我们考虑对于当前的状态q,他也是有q-1、q-2...q-k等若干个子状态转移过来的,但是这里的子状态有两种情况,一种是至少有一条边大于d,一种是没有大于d的边,所以对于同一个q来说可能存在两种状态,而在优化过程中,对这两种状态都要就行存储并且区分。

    代码

    const int maxn = 1e2+10;
    int n, k, d; ll ans, rec[maxn][3];
    int dfs(int now, bool flag) {
        if (!now) return rec[now][flag] = flag; 
        if (rec[now][flag]!=-1) return rec[now][flag];
        ll tmp = 0;
        for (int i = 1; i<=k; ++i)
            if (now-i>=0) tmp = (tmp+dfs(now-i, flag||(i>=d)))%MOD;
            //当前状态的所有可能是子状态之和,如果某个子状态没有大于d的边,那么它的值就是0
        return rec[now][flag] = tmp;
    }
    int main() {
        cin >> n >> k >> d; NIL(rec);
        cout << dfs(n,0) << endl;
        return 0;
    }
    
  • 相关阅读:
    查看数据库中指定用户下每个表占的实际空间大小
    数据库中查询列数据是否有重复
    oracle查看数据库的字符集
    【转】oracle数据库中varchar2陷阱
    cursor详解
    vs报算术运算溢出的错误
    count(1)比count(*)效率高
    基于NPOI的Execl导入导出例子
    day4-2数组及方法
    day4-1深入理解对象之创建对象
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12913843.html
Copyright © 2011-2022 走看看