您的位置:首页 > 其它

2016夏季练习——dp

2016-07-09 23:48 260 查看
来源:HDU1520

首先第一个是知道了我们的dp原来是有可能用搜索来进行推演和解释的,之前一直以为是递推的。

第二个树形dp的确是第一次看见,所以还是需要多多学习。

先来解释一下这个题目:

选一个树的非联通最大子集,其中数据是有权值

代码:

//tree-like dp
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 6005;
int con[MAXN];
vector<int> tree[MAXN];
int v[MAXN];
int dp[MAXN][2];
bool vis[MAXN];
int n;
void dfs(int root){
vis[root]=1;
dp[root][0]=0;
dp[root][1]=con[root];
int p;
for(int i=0;i<tree[root].size();i++){
p=tree[root][i];
if(vis[p]) continue;
dfs(p);
dp[root][0]+=max(dp[p][1],dp[p][0]);
dp[root][1]+=dp[p][0];
}
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(int i=1;i<=n;i++){
scanf("%d",con+i);
}
memset(v,0,sizeof(v));
int fa,son;
while(scanf("%d%d",&son,&fa)){
if(fa==0&&son==0) break;
tree[fa].push_back(son);
v[son]++;
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
if(!v[i]){
memset(vis,0,sizeof(vis));
dfs(i);
cout<<max(dp[i][0],dp[i][1])<<endl;
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: