hdu 1561 The more, The Better (依赖背包 树形dp)
题目:
链接:点击打开链接
题意:
非常明显的依赖背包。
思路:
dp[i][j]表示以i为根结点时攻击j个城堡得到的最大值。(以i为根的子树选择j个点所能达到的最优值)
dp[root][j] = max(dp[root][j],dp[root][k]+dp[u][j-k]);
u递归根结点,root当前根结点,每一个城堡之间的依赖关系形成森林。应该转化为树。再树形dp。仅仅需添加一个根结点即可。m++。
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXN 220 int num[MAXN]; int map[MAXN][MAXN];//存树 int dp[MAXN][MAXN]; int vis[MAXN]; int n,m; void dfs(int root) { vis[root] = 1; for(int i=1; i<=num[root]; i++) { int u = map[root][i]; if(!vis[u]) dfs(u); for(int j=m; j>=2; j--) { for(int k=1; k<j; k++) { if(dp[u][j-k] != -1 && dp[root][k] != -1) dp[root][j] = max(dp[root][j],dp[root][k]+dp[u][j-k]); } } } } int main() { //freopen("input.txt","r",stdin); int a,b; while(scanf("%d%d",&n,&m) != EOF && (n || m)) { memset(vis,0,sizeof(vis)); memset(dp,0,sizeof(dp)); memset(num,0,sizeof(num)); for(int i=1; i<=n; i++) { scanf("%d%d",&a,&b); dp[i][1] = b; num[a]++; map[a][num[a]] = i; } m++; for(int i=0; i<=n; i++) { dp[i][0] = 0; for(int j=2; j<=m; j++) dp[i][j] = -1; } dfs(0); printf("%d\n",dp[0][m]); } return 0; } </span>
-----------------------------------------------------------------------------------------
依赖背包的入门题。没可以自己写出来
---------------------------------------------------------------------------------------
战斗。永不停歇~~~~~~~~~~~~~~~~~~