zoukankan      html  css  js  c++  java
  • LibreOJ 10154 选课

    题目链接:LibreOJ 10154 选课

    题目大意:

    题解:
    树上的背包问题。
    不妨给所有没有先修课程的课增加先修课程(0),设(dp[i][j])表示以(i)作为根的子树修读(j)门课获得的最大学分。
    状态转移方程:

    [dp[u][i] = max{dp[u][i], dp[u][i - j] + dp[v][j]} ]

    由于想要这棵子树上的学分,(u)为必修课程,所以还需要更新一遍(u)的学分。

    [dp[u][i] = dp[u][i - 1] + score[u] ]

    答案为(dp[0][m])

    #include <cstring>
    #include <iostream>
    using namespace std;
    #define N 110
    
    int n, m, score[N], head[N], cnt, dp[N][N];
    struct Edge {
        int v, next;
    } edge[N];
    
    void addEdge(int u, int v) {
        edge[++cnt].v = v;
        edge[cnt].next = head[u];
        head[u] = cnt;
    }
    
    void dfs(int u) {
        dp[u][0] = 0;
        for (int p = head[u]; ~p; p = edge[p].next) {
            int v = edge[p].v;
            dfs(v);
            for (int i = m; i >= 0; --i) {
                for (int j = 0; j <= i; ++j) {
                    dp[u][i] = max(dp[u][i], dp[u][i - j] + dp[v][j]);
                }
            }
        }
        if (u) {
            for (int i = m; i >= 1; --i) {
                dp[u][i] = dp[u][i - 1] + score[u];
            }
        }
    }
    
    int main() {
        memset(head, -1, sizeof(head));
        cin >> n >> m;
        for (int i = 1, x; i <= n; ++i) {
            cin >> x >> score[i];
            addEdge(x, i);
        }
        dfs(0);
        cout << dp[0][m];
        return 0;
    }
    
  • 相关阅读:
    图片 音频 视频上传
    asp.net导出execl和图片
    asp.net网页播放MP4 出错
    js 定时器
    js的Math和正则
    js字符串,Arry数组,join连接,push,shift,sort
    js的argument参数
    js函数对象
    js简单语法,循环
    position的relative
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/15068378.html
Copyright © 2011-2022 走看看