zoukankan      html  css  js  c++  java
  • UVA-1220 Party at Hali-Bula (树的最大独立集)

    题目大意:数的最大独立集问题。特殊在要求回答答案是否唯一。

    题目分析:定义状态dp(i,1),dp(i,0)分别表示以i为根节点的子树选不选i最多可选的人数,f(i,1),f(i,0)分别表示以i为根节点的子树选不选i的方案唯一性。则当选i时,i的子节点都不能选,否则,可选可不选,因此状态转移方程如下:

    dp(i,1)=sum(dp(j,0)  其中,j是i的子节点

    dp(i,0)=sum(max(dp(j,1),dp(j,0)))  其中,j是i的子节点

    至于当前状态的唯一性,则受下一步决策的唯一性所影响。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<map>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    int n,dp[205][2],f[205][2];
    string p,q;
    map<string,int>mp;
    vector<int>sons[205];
    int DP(int u,int k)
    {
        if(dp[u][k]!=-1)
            return dp[u][k];
        if(sons[u].empty()){
            f[u][k]=1;
            return dp[u][k]=k;
        }
        int l=sons[u].size();
        int ans=k;
        if(k==1){
            f[u][k]=1;///唯一性受下一步决策的影响
            for(int i=0;i<l;++i){
                ans+=DP(sons[u][i],0);
                if(f[sons[u][i]][0]==0)
                    f[u][k]=0;
            }
        }else{
            f[u][k]=1;///唯一性受下一步决策的影响
            for(int i=0;i<l;++i){
                int a=DP(sons[u][i],1);
                int b=DP(sons[u][i],0);
                if(a>b){
                    ans+=a;
                    if(f[sons[u][i]][1]==0)
                        f[u][k]=0;
                }else if(a==b){
                    ans+=a;
                    f[u][k]=0;
                }else{
                    ans+=b;
                    if(f[sons[u][i]][0]==0)
                        f[u][k]=0;
                }
            }
        }
        return dp[u][k]=ans;
    }
    int main()
    {
        while(scanf("%d",&n)&&n)
        {
            mp.clear();
            memset(dp,-1,sizeof(dp));
            for(int i=1;i<=n;++i)
                sons[i].clear();
            int cnt=1;
            cin>>p;
            mp[p]=cnt++;
            for(int i=1;i<n;++i){
                cin>>p>>q;
                if(mp[p]==0)
                    mp[p]=cnt++;
                if(mp[q]==0)
                    mp[q]=cnt++;
                sons[mp[q]].push_back(mp[p]);
            }
    ///一开始以为大BOSS必须要到场,WA了两次后才意识到大BOSS应该和其他员工一视同仁!!! int a=DP(1,1),b=DP(1,0); if(a>b){ printf("%d ",a); if(f[1][1]==1) printf("Yes "); else printf("No "); }else if(a==b){ printf("%d ",a); printf("No "); }else{ printf("%d ",b); if(f[1][0]==1) printf("Yes "); else printf("No "); } } return 0; }

      

      

  • 相关阅读:
    Unique Binary Search Trees 解答
    Unique Paths II 解答
    Unique Paths 解答
    Maximum Subarray 解答
    Climbing Stairs 解答
    House Robber II 解答
    House Robber 解答
    Valid Palindrome 解答
    Container With Most Water 解答
    Remove Duplicates from Sorted List II 解答
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4793072.html
Copyright © 2011-2022 走看看