zoukankan      html  css  js  c++  java
  • hdu 4340 树状DP

    思路:我们定义两个数组,ant[Maxn][2],bob[Maxn][2]。ant[i][0]表示还未确定哪个城市被全费用占领,ant[i][1]表示确定了哪个城市被全费用占领。那么ant[i][0]的转移方程是ant[u][0]+=min(ant[v][0],bob[v][1]);即与它相连的那个城市也未确定全费用占领的城市,或者被bob占领,且确定了全费用。

    由于ant[u][0]表示未确定,故不能从ant[v][1]的确定状态转移过来。

    ant[u][1]=ant[u][0]+min(a[u],m1+a[u]/2);对于u节点确定了全费用占领城市,那么要么就是自己全费用占领,或者是他的某个相邻节点确定了全费用,所以其m1=min(m1,ant[v][1]-min(ant[v][0],bob[v][1]));表示选择相邻的某个节点确定全费用,那么就要把其未确定全费用的从ant[u][0]里减去,在赋值给ant[u][1]。

    同理bob一样。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #define Maxn 110
    #define inf 0x7fffffff
    using namespace std;
    vector<int> head[Maxn];
    int ant[Maxn][2],bob[Maxn][2],a[Maxn],b[Maxn],n,vi[Maxn];
    void init()
    {
        memset(ant,0,sizeof(ant));
        memset(bob,0,sizeof(bob));
        memset(vi,0,sizeof(vi));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=0;i<=n;i++)
            head[i].clear();
    }
    void dfs(int u)
    {
        int i,j,v,sz,temp,m1,m2;
        vi[u]=1;
        bool leaf=true;
        m1=m2=inf;
        sz=head[u].size();
        for(i=0;i<sz;i++)
        {
            v=head[u][i];
            if(vi[v]) continue;
            leaf=false;
            dfs(v);
            temp=min(bob[v][1],ant[v][0]);
            ant[u][0]+=temp;
            m1=min(m1,ant[v][1]-temp);
            temp=min(ant[v][1],bob[v][0]);
            bob[u][0]+=temp;
            m2=min(m2,bob[v][1]-temp);
        }
        if(leaf)
        {
            ant[u][1]=a[u];
            ant[u][0]=a[u]/2;
            bob[u][1]=b[u];
            bob[u][0]=b[u]/2;
        }
        else
        {
            ant[u][1]=ant[u][0]+min(a[u],m1+a[u]/2);
            ant[u][0]+=a[u]/2;
            bob[u][1]=bob[u][0]+min(b[u],m2+b[u]/2);
            bob[u][0]+=b[u]/2;
        }
    }
    int main()
    {
        int i,j,u,v,x;
        while(scanf("%d",&n)!=EOF)
        {
            init();
            for(i=1;i<=n;i++)
                scanf("%d",a+i);
            for(i=1;i<=n;i++)
                scanf("%d",b+i);
            for(i=1;i<n;i++)
            {
                scanf("%d%d",&u,&v);
                head[u].push_back(v);
                head[v].push_back(u);
            }
            dfs(1);
            printf("%d
    ",min(ant[1][1],bob[1][1]));
        }
        return 0;
    }
  • 相关阅读:
    从jvm的角度来看java的多线程
    jvm常用优化方案和方法
    JVM GC 机制与性能优化
    JVM 类加载机制详解
    (转)Java 详解 JVM 工作原理和流程
    Callable,Runnable异同
    使用Toast进行用户提醒(转)
    学好Java只需要做到这7点,年薪20W起步
    C# 之泛型详解
    C#中的委托和事件
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3245321.html
Copyright © 2011-2022 走看看