您的位置:首页 > 其它

poj 1192(简单树形dp)

2016-04-11 16:36 369 查看
题意:这题描述看似很复杂, 其实读懂后就是一个相邻点之间连通问题,水题。

解题思路:首先把相邻的点连接起来建立一棵树,dp[i][0]表示不选择i节点可以得到的最大价值,dp[i][1]表示选择i节点可以得到的最大价值。状态方程很简单,详见代码。

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

const int maxn = 1001;
struct Edge
{
int to,next;
}edge[maxn<<1];
struct Node
{
int x,y,cost;
}point[maxn];
int n,cnt,pre[maxn],dp[maxn][2]; //dp[i][0]表示不选i节点,dp[i][1]表示选i节点

void addedge(int u,int v)
{
edge[cnt].to = v;
edge[cnt].next = pre[u];
pre[u] = cnt++;
}

void dfsDP(int u,int fa)
{
dp[u][1] = point[u].cost;
dp[u][0] = 0;
int tmp = 0; //tmp记录其子节点都不选择的和
for(int i = pre[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(fa == v) continue;
dfsDP(v,u);
dp[u][0] = max(dp[u][0],dp[v][1]); //如果u不选,那么其子节点最多选择一个
tmp += dp[v][0];
dp[u][1] += max(dp[v][0],dp[v][1]); //如果选择u,那么其子节点可选可不选
}
dp[u][0] = max(dp[u][0],tmp); //考虑u的所有子节点都不选
}

int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(pre,-1,sizeof(pre));
cnt = 0;
for(int i = 1; i <= n; i++)
scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].cost);
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
if(abs(point[i].x - point[j].x) + abs(point[i].y - point[j].y) == 1)
{
addedge(i,j);
addedge(j,i);
}
dfsDP(1,0);
printf("%d\n",max(dp[1][0],dp[1][1]));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp