没有上司的晚会(party)

【问题描述】

有个公司要举行一场晚会。为了能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会邀请他的上司(上司的上司,上司的上司的上司……都可以邀请)。每个参加晚会的人都能为晚会增添一些气氛,求一个邀请方案,使气氛值的和最大。所有员工的编号为1N

 

【输入格式】

第1行一个整数N(1<=N<=6000)表示公司的人数。

接下来N行每行一个整数。第i行的数表示第i个人的气氛值x(-128<=x<=127)。

接下来每行两个整数L,K。表示K是 L的上司。

输入以0 0结束。


【输出格式】

一个数,最大的气氛值和。


【输入样例】

7

1 1 1 1 1 1 1

1 3

2 3

6 4

7 4

4 5

3 5

0 0

【输出样例】

5


【解析】

这道题..

不知道说什么.. 一开始出于习惯瞬间把森林转二叉树打完了..

结果发现根本不用..

只需要用f[i][0]和f[i][1]来存状态..

f[i][0]表示不请i的最大收益

f[i][1]表示请i的最大收益

知道这两个状态就ok了..

然后就TreeDP吧

void Tree_DP ( int x ){
	if ( f[x][0] != -1 || f[x][1] != -1 ) return;
	if ( x < 0 ) return;
	int i, j, k, f1, f0;
	f0 = 0; f1 = w[x];
	for ( k = first[x]; k; k = a[k].next ){
		Tree_DP (a[k].y);
		f1 += f[a[k].y][0];
		f0 += _max ( f[a[k].y][0], f[a[k].y][1] );
	}
	f[x][0] = f0; f[x][1] = f1;
}
大概就是这样了..

【代码】

#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int w[6100], n;
struct edgenode {
	int x, y, next;
}a[6100]; int first[6100], len;
void ins ( int x, int y ){
	len ++;
	a[len].x  = x; a[len].y = y;
	a[len].next = first[x]; first[x] = len;
}
int f[6100][2];
bool v[6100];
int _max ( int x, int y ){ return x > y ? x : y; }
void Tree_DP ( int x ){
	if ( f[x][0] != -1 || f[x][1] != -1 ) return;
	if ( x < 0 ) return;
	int i, j, k, f1, f0;
	f0 = 0; f1 = w[x];
	for ( k = first[x]; k; k = a[k].next ){
		Tree_DP (a[k].y);
		f1 += f[a[k].y][0];
		f0 += _max ( f[a[k].y][0], f[a[k].y][1] );
	}
	f[x][0] = f0; f[x][1] = f1;
}
int main (){
	int i, j, k, x, y;
	scanf ( "%d", &n );
	for ( i = 1; i <= n; i ++ ) scanf ( "%d", &w[i] );
	memset ( v, false, sizeof (v) );
	while ( scanf ( "%d%d", &x, &y ) && x != 0 || y != 0 ){
		ins ( y, x ); v[x] = true;
	}
	for ( i = 1; i <= n; i ++ ){
		if ( v[i] == false ){
			ins ( 0, i );
		}
	}
	memset ( f, -1, sizeof (f) );
	Tree_DP (0);
	printf ( "%d\n", f[0][0] );
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值