2021秋季算法入门班:B-树(树形dp,dfs序)

The shy来全dp了

在这里插入图片描述

此题一眼树形dp,但很容易被误导

  • 此题 状态转移 跟树的结点位置、形状没有关系,跟树的 dfs序 有关

d p [ i ] [ j ] dp[i][j] dp[i][j] 为选取 前 i 个 结点,使用了 前 j 种 颜色的方案数;

对于结点 i ,不需要考虑它的编号,只需要考虑它是转移中的第几个结点,从 dfs序 去转移;

有:

  • d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i − 1 ] [ j − 1 ] ∗ ( k − j + 1 ) dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(k-j+1) dp[i][j]=dp[i1][j]+dp[i1][j1](kj+1)

d p [ i ] [ j ] + = d p [ i − 1 ] [ j − 1 ] ∗ ( k − j + 1 ) dp[i][j] +=dp[i-1][j-1]*(k-j+1) dp[i][j]+=dp[i1][j1](kj+1) 我们很好理解,若前 i - 1 个结点选取的颜色都与当前结点的不同,当前结点能选择的颜色数量就是 总 数 k − ( j − 1 ) 总数k - (j-1) kj1

若当前点选择的颜色在前 i - 1 个结点选取颜色的集合中,这里的转移就比较巧妙了;对于 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i1][j] 的所有方案,当前点的颜色都只能选一种,即它的子节点的颜色,而它子节点颜色的所有情况方案都在 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i1][j] 中,所以直接转移即可。

反正就是玄学

C o d e : Code: Code:

#include<bits/stdc++.h>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define forr(a,b,c) for(int a=b;a<=c;a++)
#define rfor(a,b,c) for(int a=b;a>=c;a--)
#define endl "\n"
#define xx first
#define yy second
//[博客地址]:https://blog.csdn.net/weixin_51797626?t=1
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

const int N = 310, M = 1000010, MM = N;
int INF = 0x3f3f3f3f, mod = 1e9 + 7;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
ll dp[N][N];
//dp[i][j]:前i个节点从k种颜色选择j种染树的方案数量

int main() {
    cinios;

    cin >> n >> k;
    dp[0][0] = 1;//边界处理
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= k; j++) {
            dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] * (k - (j - 1));
            dp[i][j] %= mod;
        }
    }
    ll ans = 0;
    for (int i = 1; i <= k; i++) {
        ans += dp[n][i];
        ans %= mod;
    }
    cout << ans;

    return 0;
}
/*
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值