惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
量子位
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog
A
About on SuperTechFans
腾讯CDC
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
Last Week in AI
Last Week in AI
H
Help Net Security
WordPress大学
WordPress大学
博客园 - 司徒正美
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
博客园 - 【当耐特】
S
SegmentFault 最新的问题
美团技术团队
M
MIT News - Artificial intelligence
L
LangChain Blog
博客园 - 聂微东

某岛

AtCoder Beginner Contest 409 Luogu P5325. 【模板】Min_25 筛 UOJ #188. 【UR #13】Sanrd AtCoder Beginner Contest 371 AtCoder Beginner Contest 369 RPGMaker 2k3 百科 OneShot 的考古 2024“开创拓芯”游戏创享节的相关记录 CJ 回来后的戒断反应 Luogu P10221. [省选联考 2024] 重塑时光 Luogu P5308 [COCI2018-2019#4] Akvizna wqs 二分 歌唱王国 Lean 相关 BZOJ 3153. Sone1 The 2023 ICPC World Finals Luxor 新巴别塔 Sora 的想象与思考 Facebook Hacker Cup 2023 Round 1 AtCoder Beginner Contest 322 LLaMA 2 相关 HuggingFace AI Game Jam ACL 2023 Trans 相关… Luogu P2053. [SCOI2007] 修车 Luogu P1973. [NOI2011] NOI 嘉年华 Luogu P1933. [NOI2010] 旅行路线 Luogu P1954. [NOI2010] 航空管制 Luogu P2048. [NOI2010] 超级钢琴 Luogu P2046. [NOI2010] 海拔
树形背包
2021-09-19 · via 某岛

暴力枚举 O(n3)

const int M = int(3e2) + 9;
const int N = int(3e2) + 9;
int dp[N][M], cost[N], value[N]; VI adj[N];
int n, m;

void dfs(int u = 0) {
    FLC(dp[u], 0x80);
    DWN_1(i, m, cost[u]) dp[u][i] = value[u];

    for (auto v: adj[u]) {
        dfs(v);
        DWN_1(i, m, cost[u]) {
            FOR_1(j, cost[u], i) {
                checkMax(dp[u][i], dp[u][j] + dp[v][i-j]);
            }
        }
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
    RD(n, m);
    REP_1(i, n) {
        int p; RD(p, value[i]); cost[i] = 1;
        adj[p].push_back(i);
    }
    dfs();
    cout << dp[0][m] << endl;
}

状态继承 O(n2)

const int N = int(1e5) + 9;
const int M = int(1e5) + 9;
int cost[N], value[N]; VI adj[N];
int n, m;

void dfs(int u, int m, VI& dpu) {
    m -= cost[u];
    for (auto v: adj[u]) {
        VI dpv = dpu; dfs(v, m, dpv);
        FOR_1(i, 0, m) checkMax(dpu[i], dpv[i]);
    }
    m += cost[u];
    DWN_1(i, m, cost[u]) dpu[i] = dpu[i-cost[u]] + value[u];
    REP(i, cost[u]) dpu[i] = -INF;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
    RD(n, m);
    REP_1(i, n) {
        int p; RD(p, value[i]); cost[i] = 1;
        adj[p].push_back(i);
    }
    VI dp0; dp0.resize(m+1);
    dfs(0, m, dp0);
    cout << dp0[m] << endl;
}

P1273 有线电视网
https://www.luogu.com.cn/problem/P1273


const int N = (3e3) + 9;
VII adj[N]; int sz[N];
int dp[N][N], bonus[N];
int n, m, z;

bool isLeaf(int u) {
    return u > n-m;
}

void dfs0(int u) {
    sz[u] = isLeaf(u);
    for (auto e: adj[u]) {
        int v = e.fi;
        dfs0(v);
        sz[u] += sz[v];
    }
}

void dfs(int u) {
    FLC(dp[u], 0x80);
    dp[u][0] = 0;

    if (isLeaf(u)) {
        dp[u][1] = bonus[u];
        return;
    }

    for (auto e: adj[u]) {
        int v = e.fi, w = e.se;
        dfs(v);
        DWN_1(i, sz[u], 1) {
            REP_1(j, sz[v]) {
                checkMax(dp[u][i], dp[u][i-j] + dp[v][j] - w);
            }
        }
    }
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
    RD(n, m); REP_1(u, n-m) {
        Rush {
            int v, c; RD(v, c);
            adj[u].PB({v,c});
        }
    }

    FOR_1(u, n-m+1, n) RD(bonus[u]);

    dfs0(1); dfs(1);
    DWN_1(i, m, 0) {
        if (dp[1][i] >= 0) {
            cout << i << endl;
            return 0;
        }
    }
}

道路重建

https://www.luogu.com.cn/problem/P1272
https://www.luogu.com.cn/problem/U53878


const int N = (1e5) + 9;
VI adj[N]; int sz[N];
int n, m, z;

VI dp[N];
// dp[u][i],保留 u 节点同时子树再保留 i 个节点的子树,最少删多少边

void dfs(int u, int p){

    sz[u] = 1; dp[u].PB(0);

    for (auto v: adj[u]) if (v != p) {
        dfs(v, u);

        REP(i, SZ(dp[u])) dp[u][i] += 1;
        DO(min(sz[v], m+1-sz[u])) dp[u].PB(INF);
        sz[u] += sz[v];

        DWN(i, SZ(dp[u]), 1) {
            REP(j, min(SZ(dp[v]), i)) {
                checkMin(dp[u][i], dp[u][i-1-j] + dp[v][j] - 1);
            }
        }
    }

    if (sz[u] > m) checkMin(z, dp[u][m] + bool(p));
}

signed main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
    RD(n, m); --m; DO(n-1){
        int a, b; RD(a, b);
        adj[a].PB(b);
        adj[b].PB(a);
    }
    z = INF; dfs(1, 0);
    cout << z << endl;
}

Posted by xiaodao
Category: 日常