洛谷P1273 有线电视网

来源:互联网 发布:js 0 100两位小数 编辑:程序博客网 时间:2024/06/12 01:41

题目来源:https://www.luogu.org/problem/show?pid=1273#sub


树形背包。


f[i][j]表示在节点i处,从它的后代中选取j个的最大收益。初始化为-inf,但f[i][0]=0。


状态转移方程:f[i][j]=max(f[i][j],f[i][j-k]+f[v][k]-w)。


代码:


#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <vector>using namespace std;struct node{int t,w;};vector<node> v[3010];int t[3010];int n,m;int f[3010][3010];int dp(int pos){    if(pos>n-m)    {        f[pos][1]=t[pos];        return 1;    }    int sum=0;    for(int i=0;i<v[pos].size();i++)    {        int to=v[pos][i].t;        int co=v[pos][i].w;        int x=dp(to);        sum+=x;        for(int j=sum;j>0;j--)        {            for(int k=1;k<=x;k++)            {                f[pos][j]=max(f[pos][j],f[pos][j-k]+f[to][k]-co);            }        }    }    return sum;}int main(){    ios::sync_with_stdio(false);    memset(f,-63,sizeof(f));    cin>>n>>m;    for(int i=1;i<=n;i++)f[i][0]=0;    for(int i=1;i<=n-m;i++)    {        int k;cin>>k;        for(int j=1;j<=k;j++)        {            node c;cin>>c.t>>c.w;            v[i].push_back(c);        }    }    for(int i=n-m+1;i<=n;i++)cin>>t[i];    dp(1);    for(int i=m;i>=1;i--)    {        if(f[1][i]>=0)        {            cout<<i;            return 0;        }    }    return 0;}


0 0
原创粉丝点击