• HDU_1054 树形DP水题(树形DP小结)


    给树形DP写给小结:树形DP大致就是在在树上找递推关系。对于节点i:找其父节点fa,其子节点j之间的关系(就是向上推和向下推的做法)。一般的题目就是找子节点的关系:HDU_1054,,ZOJ_2834,HDU_1520,同时找父节点和子节点的HDU_2196。其实应该怎么找,题目读完了基本就知道了。其次还有的就是该节点的状态:dp[i][N]代表这个节点有N种状态,一种状态的好像比较少,两种状态的HDU_1054,HDU_1520,HDU_2196,三种状态的:ZOJ_2834。基本就是这些了。。。下面来说这道题:

    直接给状态转移方程:

    dp[u][0] = sum{dp[v][1]};  代表u节点没有士兵

    dp[u][1] =1+sum{dp[v][1],dp[v][0]}; 代表u节点有士兵

    下面贴代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdlib>
    #include <vector>
    #define ll  long long
    #define FOR(i,x,y)  for(int i = x;i < y;i ++)
    #define INF 1111111111
    
    using namespace std;
    
    const int MAXN = 1600;
    
    //dp[i]代表第i个节点以及其子树的所有节点都被覆盖所需要的最少士兵数
    int n,dp[MAXN][2];    //dp[i][0]代表第i个点没有士兵,dp[i][1]代表第i个点有士兵
    vector <int> G[MAXN];
    
    void dfs(int u,int fa){
        vector <int> :: iterator it;
        dp[u][0] = 0;
        dp[u][1] = 1;
        int d_value = INF;
        for(it = G[u].begin();it != G[u].end();it ++){
            int v = *it;
            if(v == fa) continue;
            dfs(v,u);
            d_value = min(d_value,dp[v][1]-dp[v][0]);
            dp[u][0] += dp[v][1];
            dp[u][1] += min(dp[v][0],dp[v][1]);
        }
    }
    
    void init_input(){
        FOR(i,0,n)  G[i].clear();
        int u,v,cnt;
        char str[30];
        FOR(i,0,n){
            scanf("%s",str);
            u = atoi(str);
            int len = strlen(str);
            FOR(i,0,len)
                if(str[i] == '(')   {cnt = atoi(str+i+1); break;}
            FOR(i,0,cnt){
                scanf("%d",&v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
        }
    }
    
    int main()
    {
        while(~scanf("%d",&n)){
            init_input();
            dfs(0,-1);
            if(n==1)    printf("1
    ");
            else printf("%d
    ",min(dp[0][0],dp[0][1]));
        }
        return 0;
    }



  • 相关阅读:
    sql语句相关操作
    点菜系统数据库课程设计
    JDBC连接mysql编程
    JFrame画图基础和事件监听
    JFrame编程
    Java基础知识
    bzoj1047-理想的正方形(二维单调队列)
    Project Eular 233/ BZOJ 1041
    Open Train 10352
    Codeforces Round 492 (Div.1)
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4555875.html
Copyright © 2020-2023  润新知