zoukankan      html  css  js  c++  java
  • 树状DP HDU1520 Anniversary party

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520

    题意:职员之间有上下级关系,每个职员有自己的happy值,越高在派对上就越能炒热气氛。但是必须是他的上司不在场的情况。求派对happy值的和最大能是多少。

    PS:这是多组输入,一开始还没看出来。。。

    dp[i][0]代表第i个职员不来的情况下的快乐值,dp[i][1]是第i个职员来的情况下的快乐值

    那很显然有

    dp[上司][来] += dp[下属][不来];
    dp[上司][不来] += Max(dp[下属][来],dp[下属][不来]);

    树状DP其实和普通DP没啥大差,就是需要遍历来确定子节点,这个题做起来还是不难的

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf=1<<30;
    const int maxn=6007;
    const double pi=acos(-1);
    const int mod=1e9+7;
    int fa[maxn];
    int root;
    int dp[maxn][2];int n;
    void dp_rule(int root){for(int i=1;i<=n;i++){
            if(fa[i]==root){
                //vis[i]=1;
                dp_rule(i);//注意这里一定要先遍历,之后再加在dp数组上 
                dp[root][0]+=max(dp[i][0],dp[i][1]);//上司不去,下属去或不去选大的一个 
                dp[root][1]+=dp[i][0];//上司去,下属只能不去 
            }
        }
    }
    int main(){
        while(~scanf("%d",&n)){
        memset(vis,0,sizeof(vis));
        memset(fa,0,sizeof(fa));
        memset(dp,0,sizeof(dp));    
        for(int i=1;i<=n;i++)scanf("%d",&dp[i][1]);//输入这里要注意啊 
        int l,k;
        while(~scanf("%d%d",&l,&k)){
            if(l==0&&k==0)break;
            fa[l]=k;        
        }
        for(int i=1;i<=n;i++){
            if(!fa[i]){
                root=i;
                break;
            }
        }
        dp_rule(root);
        int ans=max(dp[root][0],dp[root][1]);
        cout<<ans<<endl; } 
        return 0;
    }
  • 相关阅读:
    JAVA使用POI如何导出百万级别数据
    Excel最多可存多少行,多少列?
    jvm参数调优
    迭代器相应型别
    指向NULL的类
    const T & 的适用范围
    函数前修饰const与函数名后修饰const
    继承中赋值函数的注意点
    string类的简要实现
    malloc/free与new/delete的不同及注意点
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/10541766.html
Copyright © 2011-2022 走看看