vijos P1180 选课
2014-03-29 21:07
155 查看
题目地址:P1180 选课
多叉的情况不好做,所以可以转换成二叉树.
那么设dp[i][j]为以i为根节点的子树上选择j门课.
dp[i][j] = max(dp[right][j], dp[left][k - 1] +dp[right][j - k] + credit[i] | 1<= k <= j)
因为转换成了二叉树,所以任何节点i的右节点是其多叉树上的兄弟节点,左节点才是多叉树的子树.
所以dp[right][j]为把j课全部安排在兄弟节点子树上,dp[left][k - 1]为安排一门课在i上,安排k - 1门在子数上,安排j - k门在兄弟节点子树上.
总的复杂度为O(n^3)
多叉的情况不好做,所以可以转换成二叉树.
那么设dp[i][j]为以i为根节点的子树上选择j门课.
dp[i][j] = max(dp[right][j], dp[left][k - 1] +dp[right][j - k] + credit[i] | 1<= k <= j)
因为转换成了二叉树,所以任何节点i的右节点是其多叉树上的兄弟节点,左节点才是多叉树的子树.
所以dp[right][j]为把j课全部安排在兄弟节点子树上,dp[left][k - 1]为安排一门课在i上,安排k - 1门在子数上,安排j - k门在兄弟节点子树上.
总的复杂度为O(n^3)
#include <cstdio> #include <vector> #include <memory.h> using namespace std; const int MAX =305; vector<int> t[MAX]; int credit[MAX], L[MAX], R[MAX]; int dp[MAX][MAX]; int dfs(int i, int j){ if(i == -1)return 0; else if(j <= 0)return 0; else if(dp[i][j] != -1)return dp[i][j]; dp[i][j] = dfs(R[i], j); for(int m = 1; m <= j; ++m){ dp[i][j] = max(dp[i][j], dfs(L[i], m - 1) + dfs(R[i], j - m) + credit[i]); } return dp[i][j]; } int main(int argc, char const *argv[]){ int N, M; memset(L, -1, sizeof(L)); memset(R, -1, sizeof(R)); memset(dp, -1, sizeof(dp)); scanf("%d%d", &N, &M); for(int i = 1; i <= N; ++i){ int pre; scanf("%d %d", &pre, &credit[i]); t[pre].push_back(i); } for(int i = 0 ; i <= N; ++i){ if(t[i].size() > 0){ L[i] = t[i][0]; int rc = t[i][0]; for(int j = 1; j < t[i].size(); ++j){ R[rc] = t[i][j]; rc = t[i][j]; } } } printf("%d\n", dfs(0, M + 1)); return 0; }
相关文章推荐
- VijosP1180:选课
- Vijos P1180 选课(树形DP)
- / Vijos / 题库 / 选课 P1180
- 【树形dp】vijos P1180 选课
- Vijos P1180选课 解题报告
- Vijos 1180 选课(树形DP)
- Vijos 1180 选课 [树形dp]
- 集训-vijos选课(树形DP)
- 模拟学生选课系统
- 01_Vijos_1000
- 学生选课数据管理系统V0.1.0
- 选课 树状DP
- [tyvj1051]选课
- [Vijos 比赛]
- IDEF1x语义建模方法及其在数据库设计中的应用3----例子:选课系统
- HLG 1539 选课
- vijos p1311(单词接龙)
- vijos p1063(迎春舞会之集体舞)
- vijos p1014(旅行商简化版)
- 【动态规划】Vijos P1071 新年趣事之打牌