题意
给出n,m,有一颗二叉树,两个子树之间的差不超过m,二叉树的总高度为n,然后求这颗树中左右子树之间的最大差值。解析
要求最大的差值,必定就是一颗子树上的节点尽可能地多,另一个尽可能的少,尽可能多的很容易就能解决,就是挂满就完事了,即 $2^{n-1}-1$,现在就是解决另一颗子树如何做到最少,这里我们可以通过递推,假设m为2,假设我们已经知道了$dp[1],dp[2]$现在求解$dp[3]$那么因为我们要求就是在的基础上再向上加一个节点,这个就是那个加一,然后我们再挂一颗子树在另一边,这另一颗子树自然是尽可能地小,最大的差值就是m,所以挂在另一边的就是
因此我们可以得出递推式
但是我们还要小心
所以最后的结果为
代码
#include <cctype> #include <cfloat> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <algorithm> #include <deque> #include <fstream> #include <functional> #include <iomanip> #include <iostream> #include <istream> #include <iterator> #include <list> #include <map> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <utility> #include <vector> #include <unordered_map> #include <unordered_set> #define ll long long using namespace std; const int N = 1e5 + 7; ll dp[100]; int main(void) { int n,m; cin>>n>>m; dp[1] = 1; for (int i = 2; i <= n; ++i) dp[i] = dp[i - 1] + dp[max(i - m - 1, 0)] + 1; ll ans = 1ll<< n - 1; ans -= dp[n - m - 1]; cout << ans - 1 << endl; return 0; }