• 【luogu1273】 有线电视网 [动态规划 树形dp]


    P1273 有线电视网

    好早之前就叫做的题了qwq 我太垃圾了现在才跑来把它做了

    f[i][j]表示当前节点i 选了j个用户 

    其实不用建双向的 因为是一个以1为根节点的树 而且它按顺序输入qwq

    #include<bits/stdc++.h>
    using namespace std;
    #define Max(x,y) (x)>(y)?(x):(y)
    #define Min(x,y) (x)>(y)?(y):(x)
    #define ll long long
    #define rg register
    const int N=3000+5,M=10000+5,inf=0x3f3f3f3f,P=99999997;
    int n,m,f[N][N],ans,a[N];
    bool vis[N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N<<1],tot=0;
    struct edge{int v,w,nxt;}e[N<<1];
    void add(int u,int v,int w){
        e[++tot]=(edge){v,w,head[u]},head[u]=tot;
    }
    
    int dp(int u){
        vis[u]=1;
        if(u>n-m) {f[u][1]=a[u];return 1;}
        int size=0,vsize;
        for(int i=head[u],v;i;i=e[i].nxt){
            v=e[i].v;
            if(vis[v]) continue;
            vsize=dp(v),size+=vsize;
            for(int k=size;k;--k)
            for(int j=1;j<=vsize;++j)
            if(k-j>=0) f[u][k]=Max(f[u][k],f[u][k-j]+f[v][j]-e[i].w);
        }
        return size;
    }
    
    int main(){
        freopen("in.txt","r",stdin);
        rd(n),rd(m);
        for(int i=1,k,v,w;i<=n-m;++i){
            rd(k);
            while(k--) rd(v),rd(w),add(i,v,w),add(v,i,w);
        }
        memset(f,-inf,sizeof(f));
        for(int i=1;i<=m;++i) rd(a[i+n-m]);
        for(int i=1;i<=n;++i) f[i][0]=0;for(int i=m;i;--i)
        if(f[1][i]>=0){ans=i;break;}
        printf("%d",ans);
        return 0;
    }
     
  • 相关阅读:
    第二次作业
    动手动脑
    第五周总结
    第四周总结
    二维数组
    返回一个整数数组中最大子数组的和---第一次完善
    第三周总结
    第二周进度
    自我介绍
    返回一个整数数组中最大子数组的和
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11206345.html
Copyright © 2020-2023  润新知