zoukankan      html  css  js  c++  java
  • P3047 [USACO12FEB]附近的牛Nearby Cows 树形dp

    题目简述:给出一棵n个点的树,每个点上有C_i头牛,问每个点k步范围内各有多少头牛。

    如果 i点由其相连的点进行转移 dp[i][j]+=dp[v][j-1]  这样会有重复的情况

    可以发现  重复是由j-2造成的!!!! 想一想

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=100000+5;
    const int M=2*N;
    int head[M],pos;
    struct Edge
    {
        int nex,to,v;
    }edge[M];
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].to=b;
    }
    int n,m;
    int dp[N][30];
    int vis[N];
    
    int main()
    {
        RII(n,m);
        rep(i,1,n-1)
        {
            int a,b;RII(a,b);
            add(a,b);add(b,a);
            vis[a]++;vis[b]++;
        }
        rep(i,1,n)
        RI(dp[i][0]);
    
        rep(j,1,m)
        rep(i,1,n)
        {
            for(int s=head[i];s;s=edge[s].nex)
            dp[i][j]+=dp[edge[s].to][j-1];
            if(j>1)dp[i][j]-=(vis[i]-1)*dp[i][j-2];
            
            if(j==1)dp[i][j]+=dp[i][0];
        }
        rep(i,1,n)
        cout<<dp[i][m]<<endl;
    
        return 0;
    }
    View Code

    另一种写法:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define re register
    #define maxn 100001
    using namespace std;
    struct node
    {
        int v,nxt;
    }e[maxn<<1];
    int f[maxn][21],s[maxn],head[maxn],deep[maxn];
    int n,num,k;
    inline int read()
    {
        char c=getchar();
        int x=0;
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9')
          x=(x<<3)+(x<<1)+(c^48),c=getchar();
        return x;
    }
    inline void add(int x,int y)
    {
        e[++num].v=y;
        e[num].nxt=head[x];
        head[x]=num;
    }
    inline void build(int r)
    {
        for(re int i=head[r];i;i=e[i].nxt)
        if(!deep[e[i].v])
        {
            deep[e[i].v]=deep[r]+1;
            build(e[i].v);
            for(re int j=1;j<=k;j++)
            f[r][j]+=f[e[i].v][j-1];
        }
    }
    inline void dfs(int r)
    {
        for(re int i=head[r];i;i=e[i].nxt)
        if(deep[e[i].v]>deep[r])
        {
            for(re int j=k;j>=2;j--)
                f[e[i].v][j]-=f[e[i].v][j-2];//简单的容斥原理了
              //这里的循环一定要倒序
            for(re int j=1;j<=k;j++)
                f[e[i].v][j]+=f[r][j-1];
            dfs(e[i].v);
        }
    }
    int main()
    {
        n=read();
        k=read();
        int x,y;
        for(re int i=1;i<n;i++)
        {
            x=read();
            y=read();
            add(x,y);
            add(y,x);
        }
        for(re int i=1;i<=n;i++)
            s[i]=read(),f[i][0]=s[i];
        deep[1]=1;
        build(1);
        dfs(1);
        for(re int j=1;j<=n;j++)
        {
            int ans=0;
            for(re int i=0;i<=k;i++)
            ans+=f[j][i];
            printf("%d
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    IDEA中用jetty启动项目时,url 404
    Mysql 性能查询
    RabbitMQ 安装
    Ubuntu安装kubernetes
    .net 4 调用WCF时报错 Type 'System.Threading.Tasks.Task`1[]' cannot be serialized
    Windows XP SP2上安装.net 4
    angular学习的一些Mark
    [转]对 td 使用 overflow:hidden; 无效的几点错误认识
    静态方法与非静态方法的区别
    二进制字符串的权限管理
  • 原文地址:https://www.cnblogs.com/bxd123/p/10840447.html
Copyright © 2011-2022 走看看