POJ1192最优连通子串----树形dp
中文题面,目的很明显,把相邻的两个点看成是两个点之间有一条边,就能当成树形dp来做了。
用一遍dfs可以找出最大的子树权值和。
#include<iostream> #include<vector> #include<queue> #include<string.h> #include<stdio.h> #include<map> using namespace std; #define p pair<int,int> map<p,int> mp,pd; int a[2010][2010],ans=0; int dfs(int x,int y) { //cout<<x<<" "<<y<<endl; int d; if(mp[p(x,y)]==999) d=0; else d=mp[p(x,y)]; //cout<<d<<" "; pd[p(x,y)]=1; if(mp[p(x+1,y)]==0||pd[p(x+1,y)]!=0) ; else d+=dfs(x+1,y); if(mp[p(x,y+1)]==0||pd[p(x,y+1)]!=0) ; else d+=dfs(x,y+1); if(mp[p(x-1,y)]==0||pd[p(x-1,y)]!=0) ; else d+=dfs(x-1,y); if(mp[p(x,y-1)]==0||pd[p(x,y-1)]!=0) ; else d+=dfs(x,y-1); ans=max(ans,d); //cout<<d<<endl; if(d>0) return d; else return 0; } int main() { int n,i,j,k,l,x,y,z; cin>>n; for(i=0;i<n;i++) { cin>>x>>y>>z; if(z==0) z=999; mp[p(x,y)]=z; //用于标记该点是否存在,为了避免0的干扰,对权值为0的点特判 pd[p(x,y)]=0;//标记这个点(x,y)是否遍历到过 } dfs(x,y); cout<<ans<<endl; }