标签:div ssi not day ref return scanf from pig
poj-2486-Apple Tree
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11210 | Accepted: 3774 |
Description
Input
Output
Sample Input
2 1 0 11 1 2 3 2 0 1 2 1 2 1 3
Sample Output
11 2
Source
17857578 | 2486 | Accepted | 892K | 63MS | G++ | 1191B | 2017-11-18 19:26:17 |
树状DP。
本题的关键在于建立dp转化方程。
dp[x][j][0] = max( dp[x][j][0], dp[x][j-t][1] + dp[y][t-1][0] );
表示的是不回到当前x点的话,是回到j - t 步的x当前点 加上 不回到 y 点的步骤
dp[x][j][0] = max(dp[x][j][0], dp[x][j-t][0] + dp[y][t-2][1] );
表示的 不回到当前x点。 是 不回到当前 x 点 和 回到y点的 之和。
dp[x][j][1] = max(dp[x][j][1], dp[x][j-t][1] + dp[y][t-2][1] );
表示回到当前x点, 是回到x点和回到子结点y的总和。
// poj-2486 #include <cstdio> #include <cstring> #include <iostream> #include <vector> using namespace std; const int MAXN = 100 + 10; int n, k, val[MAXN], vis[MAXN], dp[MAXN][2*MAXN][2]; vector<int> vt[MAXN]; void dfs(int x){ vis[ x ] = 1; for(int i=0; i<vt[x].size(); ++i){ int y = vt[x][i]; if(vis[ y ] == 1){ continue; } dfs(y); for(int j=k; j>=1; --j){ for(int t=1; t<=j; ++t){ dp[x][j][0] = max( dp[x][j][0], dp[x][j-t][1] + dp[y][t-1][0] ); if(t >= 2){ dp[x][j][0] = max(dp[x][j][0], dp[x][j-t][0] + dp[y][t-2][1] ); dp[x][j][1] = max(dp[x][j][1], dp[x][j-t][1] + dp[y][t-2][1] ); } } } } } int main(){ freopen("in.txt", "r", stdin); int a, b, ans; while(scanf("%d %d", &n, &k) != EOF){ memset(dp, 0, sizeof(dp)); memset(vis, 0, sizeof(vis)); for(int i=1; i<=n; ++i){ scanf("%d", &val[i]); for(int j=0; j<=k; ++j){ dp[i][j][0] = dp[i][j][1] = val[i]; } } for(int i=1; i<=n; ++i){ vt[i].clear(); } for(int i=1; i<n; ++i){ scanf("%d %d", &a, &b); vt[a].push_back(b); vt[b].push_back(a); } dfs(1); ans = max(dp[1][k][0], dp[1][k][1]); printf("%d\n", ans ); } return 0; }
标签:div ssi not day ref return scanf from pig
原文地址:http://www.cnblogs.com/zhang-yd/p/7857718.html