Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8670 | Accepted: 2882 |
Description
Input
Output
Sample Input
2 1 0 11 1 2 3 2 0 1 2 1 2 1 3
Sample Output
11 2
一棵树,每个结点上有有一些苹果,从1开始最多只能走K步,能吃到多少苹果。
dp[i][j][0]表示从结点i往下走不超过j步并且回到结点i的最大值,dp[i][j][1]表示从结点i往下走不超过j步并且但不一定回到结点i的最大值,进行状态转移时注意dp[i][j][1]有两种情况,从左边走回来再往右走和从右边走回来再往左走。
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long LL; const LL MAXN=110; const LL MAXM=15; const LL INF=0x3f3f3f3f; int N,K; int dp[MAXN][2*MAXN][2],a[MAXN]; vector<int> g[MAXN]; void dfs(int u,int fa){ int len=g[u].size(); if(len<=1&&g[u][0]==fa) return; for(int i=0;i<len;i++){ int v=g[u][i]; if(v!=fa){ dfs(v,u); for(int j=K;j>0;j--){ for(int k=0;k<=j-2;k++) dp[u][j][0]=max(dp[u][j][0],dp[v][k][0]+dp[u][j-k-2][0]); for(int k=0;k<=j-2;k++) dp[u][j][1]=max(dp[u][j][1],dp[v][k][0]+dp[u][j-k-2][1]); for(int k=0;k<j;k++) dp[u][j][1]=max(dp[u][j][1],dp[v][k][1]+dp[u][j-k-1][0]); } } } } int main(){ freopen("in.txt", "r", stdin); while(scanf("%d%d",&N,&K)!=EOF){ for(int i=1;i<=N;i++) scanf("%d",&a[i]); for(int i=1;i<=N;i++) g[i].clear(); int u,v; for(int i=0;i<N-1;i++){ scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } if(N==1){ printf("%d\n",a[1]); continue; } memset(dp,0,sizeof(dp)); for(int i=1;i<=N;i++) dp[i][0][0]=dp[i][0][1]=a[i]; dfs(1,-1); printf("%d\n",dp[1][K][1]); } return 0; }