樹形dp poj-2342與codeforces Round #525(Div 2)E
阿新 • • 發佈:2018-12-23
poj-2342
題目連結:http://poj.org/problem?id=2342
很簡單的樹形dp,狀態方程是:
dp[i][1]+=dp[j][0] (在選擇 i 的情況,j 是 i 的下屬 )
dp[i][0]+=max(dp[j][0],dp[j][1]) (在不選擇 i 的情況,i的下屬 j 可選可不選 )
ac code:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<vector> using namespace std; #define N 30005 struct edge { int v; struct edge* f; }; edge* a[N]; vector<int>b[N]; int dp[N][2]; int n, root; void trees(int edg) { if (b[edg].size() == 0) { return; } for (int i = 0; i < b[edg].size(); i++) { trees(b[edg][i]); dp[edg][1] += dp[b[edg][i]][0]; dp[edg][0] += max(dp[b[edg][i]][0], dp[b[edg][i]][1]); } } int main() { int L, K; memset(dp, 0, sizeof(dp)); scanf("%d", &n); for (int i = 1; i <= n; i++) { a[i] = new edge; a[i]->f = NULL; } for (int i = 1; i <= n; i++) { scanf("%d", &a[i]->v); } while (~scanf("%d%d", &L, &K) && !(L == 0 && K == 0)) { a[L]->f = a[K]; b[K].push_back(L); } for (int i = 1; i <= n; i++) { dp[i][1] = a[i]->v; if (a[i]->f == NULL) { root = i; } } trees(root); cout << max(dp[root][1], dp[root][0]) << endl; return 0; }
codeforces Round #525(Div 2)E
題目連結:http://codeforces.com/contest/1088/problem/E
題解:
ac code:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<set> #include<vector> #include<queue> using namespace std; #define N 300005 long long dp[N]; int n, a[N]; long long sum = -1e9; int k = 0; vector<int>q[N]; void dfs(int root, int p, int l) { dp[root] = a[root]; for (int i = 0; i < q[root].size(); i++) { if (q[root][i] != p) { dfs(q[root][i], root, l); if (dp[q[root][i]] > 0) { dp[root] += dp[q[root][i]]; } } } if (l) { sum = max(sum, dp[root]); //cout << sum << " " << root << endl; } else { if (dp[root] == sum) { dp[root] = 0; k++; } } } int main() { int u, v; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for (int i = 1; i < n; i++) { scanf("%d%d", &u, &v); q[u].push_back(v); q[v].push_back(u); } dfs(1, 0, 1); dfs(1, 0, 0); printf("%I64d %d", sum*k, k); return 0; }