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; }

      

      

  • 相关阅读:
    HashMap按键排序和按值排序
    LeetCode 91. Decode Ways
    LeetCode 459. Repeated Substring Pattern
    JVM
    LeetCode 385. Mini Parse
    LeetCode 319. Bulb Switcher
    LeetCode 343. Integer Break
    LeetCode 397. Integer Replacement
    LeetCode 3. Longest Substring Without Repeating Characters
    linux-网络数据包抓取-tcpdump
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4793072.html
Copyright © 2011-2022 走看看