zoukankan      html  css  js  c++  java
  • 洛谷 P1273 有线电视网(dp)

    /*
    想了半天没想出状态 自己还是太弱了 QAQ
    题目问的是最多供给多少户 一般想法是把这个值定义为状态量
    没想出来QAQ....看了看题解的状态 很机智.... 
    f[i][j]表示i的子树 选了j个叶子的最大收益
    这样 不亏本就是收益>=0 
    转移的话 先搜一下这个子树有几个叶子 然后枚举儿子 
    枚举当前儿子分几个叶子 这里的枚举顺序有套路
    从大到小枚举i分几个 从小到大枚举j分几个
    这样可以避免 重复选择 
    注意初始化 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 3010
    using namespace std;
    int n,m,p,head[maxn],num,f[maxn][maxn],ans,c[maxn];
    struct node{
        int v,t,pre;
    }e[maxn];
    void Add(int from,int to,int dis){
        num++;e[num].v=to;
        e[num].t=dis;
        e[num].pre=head[from];
        head[from]=num; 
    }
    int Dfs(int u)
    {
        if(u>p){
            f[u][1]=c[u];
            return 1;
        }
        int s=0;
        for(int i=head[u];i;i=e[i].pre){
            int v=e[i].v;
            int x=Dfs(v);s+=x;
            for(int j=s;j>=1;j--)
                for(int k=1;k<=x;k++)
                    f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]-e[i].t);
        }
        return s;
    }
    int main()
    {
        scanf("%d%d",&n,&m);p=n-m;
        for(int i=1;i<=p;i++){
            int x,y,z;
            scanf("%d",&x);
            for(int j=1;j<=x;j++){
                scanf("%d%d",&y,&z);
                Add(i,y,z);
            }
        }
        for(int i=p+1;i<=n;i++)
            scanf("%d",&c[i]);
        memset(f,-127/3,sizeof(f));
        for(int i=1;i<=n;i++)
            f[i][0]=0;
        Dfs(1);
        for(int i=0;i<=m;i++)
            if(f[1][i]>=0)ans=max(ans,i);
        printf("%d
    ",ans);
        return 0;
    } 
  • 相关阅读:
    Java 访问标识符
    Java 类变量与实例变量的区别
    Java 变量
    python install sublime安装
    Failed to resolve com.android.support:support-annotations 26.0.1
    Git的使用及托管代码到GitHub
    Recyclerview点击事件,更新item的UI+更新Recyclerview外的控件
    第一次android混淆实战
    android计算屏幕dp
    显示当前日期时间
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5831446.html
Copyright © 2011-2022 走看看