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[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;
}
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray