思路:
树形背包DP
#include<cstdio> #include<iostream> #include<string> #include<queue> #include<cstring> using namespace std; const int maxn = 110; void qread(int &x){ x = 0; register int ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9') x = 10 * x + ch - 48, ch = getchar(); } int n, m; int head[maxn]; int go[maxn << 1]; int nxt[maxn << 1]; int wor[maxn]; int dp[maxn][maxn]; void init(){ qread(m); qread(n); for(int i=1; i<=m; ++i){ int x; qread(x), qread(wor[i]); go[i] = i; nxt[i] = head[x]; head[x] = i; } memset(dp, 0xcf, sizeof(dp)); } void DP(int x){ dp[x][0] = 0; for(register int i = head[x]; i; i = nxt[i]){ DP(go[i]); for(int t = m; t >= 0; --t){ for(int j = t; j >= 0; --j) if(t - j >= 0) dp[x][t] = max(dp[x][t], dp[x][t - j] + dp[go[i]][j]); } } if(x != 0) for(int t = m; t > 0; --t) dp[x][t] = dp[x][t - 1] + wor[x]; } int main(void){ init(); DP(0); cout << dp[0][n] << endl; }