Description
Input
Output
Sample Input
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
Sample Output
5
Source
本题题意::公司的员工们根据上下级关系可以形成树状的结构。在参加party中每个人都有一个rating,为了和谐,不让员工和他的直属上级同时存在,求最大的rating。
思路::用 fa 数组记录直属上司,vector son 数组直属下属,dp 数组记录最大的rating。dp[i][0]表示i不参加的最大rating、dp[i][1]表示i参加的最大rating。
那么状态转移方程为:dp[ i ][ 0 ] = dp[ i ][ 0 ] + max ( dp[ j ][ 0 ] , dp[ j ][ 1 ] ); j 为每一个 i 的直属下属
dp[ i ][ 1 ] = dp[ i ][ 1 ] + dp[ j ][ 0 ] ; i 参加,i的所有直属下属都不能参加
代码::#include <iostream> #include <sstream> #include <ios> #include <iomanip> #include <functional> #include <algorithm> #include <vector> #include <string> #include <list> #include <queue> #include <deque> #include <stack> #include <set> #include <map> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <climits> #include <cctype> using namespace std; #define XINF INT_MAX #define INF 0x3FFFFFFF #define MP(X,Y) make_pair(X,Y) #define PB(X) push_back(X) #define REP(X,N) for(int X=0;X<N;X++) #define REP2(X,L,R) for(int X=L;X<=R;X++) #define DEP(X,R,L) for(int X=R;X>=L;X--) #define CLR(A,X) memset(A,X,sizeof(A)) #define IT iterator typedef long long ll; typedef pair<int,int> PII; typedef vector<PII> VII; typedef vector<int> VI; /*************************************** ****************头文件****************** ***************************************/ int fa[6005];//记录父亲节点 vector<int> son[6005];//记录所有的孩子节点 int dp[6005][2];//dp[i][0]表示i不参加的最大值dp[i][1]表示i参加的最大值 void dfs(int i) { REP(j,son[i].size()){ //遍历每一个i的直属下属 dfs(son[i][j]); //至于这里遍历的不是 j ,而是son[i][j].我就错了好久,最后调试才发现问题 dp[i][0] += max(dp[son[i][j]][0],dp[son[i][j]][1]);//看思路 dp[i][1] += dp[son[i][j]][0]; } } int main() { int N; while(cin>>N) { REP(i,6005) son[i].clear();//不能忘记初始化 memset(dp,0,sizeof(dp); memset(fa,-1,sizeof(fa)); REP2(i,1,N){ cin>>dp[i][1];//当i参加时,最初应为自己的rating } int L,K; while(cin>>L>>K&&!(L==0&&K==0)){ fa[L] = K; //构建树,记录父亲结点 son[K].PB(L); //记录孩子节点 } int ans = 0; //记录答案,初始化 /*REP2(i,1,N) REP(j,son[i].size()) cout<<i<<" "<<son[i][j]<<endl;*/ REP2(i,1,N){ if(fa[i] == -1){ //当父亲节点为-1时找到root进行遍历 dfs(i); ans+=max(dp[i][0],dp[i][1]);//如果有多个树根,要把每一个的最大rating加起来 } } cout<<ans<<endl;//输出来就对了 } return 0; }不算很难,思路清楚了,就一目了然。