zoukankan      html  css  js  c++  java
  • 树 (DP,dfs序,组合数学,思维)

    题目:传送门

    题意

    1 <= n, k <= 300

    思路

    这题邓老师用的是 dfs 序做的 --> 戳我

    用dfs序的话,是 o(nk)的,复杂度略高

    这题还可以用另一种思维做;

    可以将染色转化为,将一颗树分成若干连通块,连通块里的颜色都相同,不同连通块的颜色不同;

    把一颗树分成不同的两个连通块就是删除一条边,那分成 x 块就是删掉 x - 1 条边;那方案数就是 C(n - 1, x - 1);

    然后选 x 种颜色有 C(k, x) 种方案,将 x 种颜色染到 x 个连通块上有 x! 种方案;

    这样的复杂度是很接近 o(n) 的

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int N = 1e6 + 5;
    
    const LL mod = 1e9 + 7;
    
    int n, k, u, v;
    
    LL dp[305][305];
    
    void solve() {
    
        scanf("%d %d", &n, &k);
    
        rep(i, 1, n - 1) scanf("%d %d", &u, &v);
        
        dp[0][0] = 1LL;
        
        rep(i, 1, n) rep(j, 1, k) dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1] * (k - j + 1) % mod) % mod;
        
        LL ans = 0LL;
        
        rep(i, 1, k) ans = (ans + dp[n][i]) % mod;
        
        printf("%lld
    ", ans);
        
    }
    
    
    int main() {
    
    //    int _; scanf("%d", &_);
    //    while(_--) solve();
    
        solve();
    
        return 0;
    }
    dfs序
    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int N = 1e6 + 5;
    
    const LL mod = 998244353;
    
    int ans[10];
    
    void calr(int x) {
    
        for(int l = 1, r; l <= x; l = r + 1) {
    
            r = x / (x / l);
    
    
    
        }
    
    }
    
    void call(int x) {
    
    
    
    }
    
    
    void solve() {
    
        int l, r;
    
        scanf("%d %d", &l, &r);
    
        calr(r);
    
        call(l - 1);
    
        rep(i, 1, 9) printf("%d
    ", ans[i])
    
    }
    
    
    int main() {
    
    //    int _; scanf("%d", &_);
    //    while(_--) solve();
    
        solve();
    
        return 0;
    }
    组合数
  • 相关阅读:
    LINQ基础——WHERE子句
    LINQ基础——LET子句
    LINQ基础——FROM子句
    Guid(全局统一标识符)
    ??运算符
    多线程的AutoResetEvent
    线程池(ThreadPool)
    Mutex
    Monitor类实现线程同步
    【java框架】MyBatis(7)--MyBatis注解开发
  • 原文地址:https://www.cnblogs.com/Willems/p/13683372.html
Copyright © 2011-2022 走看看