[LGOJ1273]有线电视网

Posted yangxuejian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LGOJ1273]有线电视网相关的知识,希望对你有一定的参考价值。

solution

用了一个很有意思的转移方法。

$dp[i][j] $ 表达 (i) 作为根,(j)个终端时最大的收益,即钱数,当(0leq dp[1][i])时,即以1为根可以转移到(i)个终端,且不亏本,此时(i)也最大时,i就是答案。

然后就是树上背包的套路题了。。

[dp[u][j] = max(dp[u][j], dp[u][j - k]+dp[v][k]-len(u, v))]

自己思考一下。

code

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3000 + 5;
int n, m, a[maxn], dp[maxn][maxn]; // id & zhongduan_num;
struct node {int to, z;};
vector <node> e[maxn];
int dfs(int x) {
    if(x > n - m) {
        dp[x][1] = a[x];
        return 1;
    }
    int sum = 0;
    for(int i = 0;i < e[x].size();i ++) {
        int y = e[x][i].to, z = e[x][i].z, son = dfs(y);
        sum += son;
        for(int v = sum; v >= 0; v --) {
            for(int j = 1;j <= min(son, v);j ++) {
                dp[x][v] = max(dp[x][v], dp[x][v - j] + dp[y][j] - z);
            }
        }
    }
    return sum;
}
int main() {
    memset(dp, 0xcf, sizeof(dp));
    cin >> n >> m;
    for(int i = 1;i <= n;i ++) 
        dp[i][0] = 0;
    for(int i = 1, A, C;i <= n - m;i ++) {
        int k; cin >> k;
        for(int j = 1;j <= k;j ++) {
            cin >> A >> C;
            e[i].push_back((node){A, C});
        }
    } 
    for(int i = 1;i <= m;i ++) {
        cin >> a[n - m + i];
    }
    dfs(1);
    for(int i = m;i >= 1;i --) {
        if(dp[1][i] >= 0) {
            cout << i;
            return 0;
        }
    }
    puts("0");
    return 0;
}

thanks

以上是关于[LGOJ1273]有线电视网的主要内容,如果未能解决你的问题,请参考以下文章

P1273 有线电视网

P1273 有线电视网

洛谷 P1273 有线电视网

[P1273]有线电视网

洛谷1273:有线电视网——题解

P1273 有线电视网