POJ 1155 TELE 树状DP
2013-06-29 11:36
309 查看
以DP[i][j]表示以第i个点为根节点的树获得j个用户能够赚的最大值,最后查找DP[1][j]值不小于零的最大j值就是答案,注意DP的初始化,刚开始只初始了一部分,结果苦逼的Wrong了,应该所有值都要初始为最小值。
#include <cstdio> #include <cstring> #include <iostream> #include <queue> #include <algorithm> #include <map> #include <vector> #include <stack> using namespace std; #define M 3005 #define ll unsigned long long #define int64 __int64 #define inf 1<<30 struct node { int cost , e; }; vector<node> tree[M]; int n , m , dp[M][M] , pay[M]; int Dfs(int rt) { dp[rt][0] = 0; if (rt > n-m) { dp[rt][1] = pay[rt]; return 1; } int i , j , k , up = tree[rt].size() , sum = 0; //sum记录当前点下面的用户数量 for (i = 0 ; i < up ; i++)sum += Dfs(tree[rt][i].e); for (i = 0 ; i < up ; i++) { for (j = sum ; j > 0 ; j--)//若直接从m开始循环,会超时的 { for (k = 1 ; k <= j ; k++) { dp[rt][j] = max(dp[rt][j] , dp[tree[rt][i].e][k]+dp[rt][j-k]-tree[rt][i].cost); } } } return sum; } int main() { int i , j; while (~scanf("%d%d",&n,&m)) { for (i = 1 ; i <= n-m ; i++) { int k; node a; scanf("%d",&k); while (k--)scanf("%d%d",&a.e,&a.cost),tree[i].push_back(a); } for (i = n-m+1 ; i <= n ; i++)scanf("%d",pay+i); for (i = 0 ; i <= n ; i++) for (j = 0 ; j <= m ; j++) dp[i][j] = -(1<<20); Dfs(1); int ans = 0; for (i = 1 ; i <= m ; i++) { if (dp[1][i] >= 0)ans = i; } printf("%d\n",ans); for (i = 0 ; i <= n ; i++)tree[i].clear(); } return 0; }
相关文章推荐
- POJ 1155 TELE [树状DP]
- POJ 1155 TELE (树状DP)
- POJ-1155--TELE--树形DP
- POJ 1155 TELE 树形DP
- POJ 1155 TELE 树形DP
- poj 1155 TELE (树形dp)
- poj 1155 TELE 树形dp泛化背包
- POJ 1155 TELE(树形DP)
- poj 1155 TELE (树形dp)
- POJ 1155 TELE【树形DP】
- poj 1155 TELE (树形背包dp)
- POJ1155:TELE(树形DP)
- poj 1155 TELE(树形泛化背包dp)
- POJ 1155 TELE 树形dp
- POJ 1155 - TELE 树形DP(泛化背包转移)..
- poj 1155 TELE(树形DP)
- POJ 1155 TELE(树形DP)
- POJ1155 TELE(树形DP)
- POJ 1155 TELE 背包型树形DP 经典题
- POJ 1155 树形背包(DP) TELE