【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 108471
  • 排名 - 229

最新评论

阅读排行榜

评论排行榜

Ural周立大学的校长正在筹备学校的80周年纪念聚会。由于学校的职员有不同的职务级别,可以构成一棵以校长为根的人事关系树。每个职员都有一个唯一的整数编号(范围在1到N之间),并且对应一个参加聚会所获得的欢乐度。为了使每个参加聚会者都感到欢乐,校长想设法使每个职员和他(她)的直接上司不会同时参加聚会。

你的任务是设计一份参加聚会者的名单,使总的欢乐度最高。

输入:
第一行是一个整数N,1<= N <= 6000
以下的N行是对应的N个职员的欢乐度(欢乐度是一个从-128到127之间的整数)
接着是学校的人事关系树,树的每一行格式如下:<L> <K>
表示第K个职员是第L个职员的直接上司。
输入以0 0表示结束

输出:
参加聚会者获得的最大总欢乐度

Sample Input
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

Sample Output
5

分析:
   F[0][i]表示不邀请i的上司的最大欢乐度。 F[1][i]表示邀请i的上司的最大欢乐度。
   状态方程:F[0][i]+=F[1][i的职员];
             F[1][i]+=max(F[1][i的职员],F[0][i的职员]);
   answer=max(F[0][root],F[1][root]);

【参考程序】:

#include<cstring>
#include
<cstdio>
#include
<iostream>
using namespace std;

int F[2][6010],now[6010],next[6010],child[6010];
int n,root;
int Max(int a,int b)
{
    
return a>b?a:b;
}
void tree_dp(int k)
{
    
while (now[k])
    {
        tree_dp(child[now[k]]);
        F[
0][k]+=F[1][child[now[k]]];
        F[
1][k]+=Max(F[1][child[now[k]]],F[0][child[now[k]]]);
        now[k]
=next[now[k]];
    }
}
int main()
{
    scanf(
"%d",&n);
    
for (int i=1;i<=n;i++)
    {
        scanf(
"%d",&F[0][i]);
        now[i]
=next[i]=child[i]=0;
    }
    root
=(n+1)*n/2;
    
int k,l;
    
for (int i=1;i<=n-1;i++)
    {
        scanf(
"%d%d",&l,&k);
        next[i]
=now[k]; now[k]=i;
        child[i]
=l; root-=l;
    }
    tree_dp(root);
    printf(
"%d\n",Max(F[0][root],F[1][root]));
    
return 0;
}

【参考程序】:

#include<cstring>
#include
<cstdio>
#include
<iostream>
using namespace std;

int F[2][6010],father[6010];
bool vis[6010];
int n,root;
int Max(int a,int b)
{
    
return a>b?a:b;
}
void tree_dp(int k)
{
    vis[k]
=true;
    
for (int i=1;i<=n;i++)
        
if (!vis[i] && father[i]==k)
        {
            tree_dp(i);
            F[
0][k]+=F[1][i];
            F[
1][k]+=Max(F[1][i],F[0][i]);
        }
}
int main()
{
    scanf(
"%d",&n);
    
for (int i=1;i<=n;i++)
    {
        scanf(
"%d",&F[0][i]);
        father[i]
=0;
    }
    root
=0bool bk=true;
    
int l,k;
    
while (scanf("%d%d",&l,&k),l+k>0)
    {
        father[l]
=k;
        
if (root==|| bk)
        {
            root
=k; bk=false;
        }
    }
    memset(vis,
false,sizeof(vis));
    tree_dp(root);
    printf(
"%d\n",Max(F[0][root],F[1][root]));
    
return 0;
}


 

posted on 2009-08-24 10:40 开拓者 阅读(604) 评论(0)  编辑 收藏 引用 所属分类: 树形DP

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理