http://acm.pku.edu.cn/JudgeOnline/problem?id=1155
Код:
#include <iostream> #include <climits> #include <list> using namespace std; const int BUFLEN = 10240; int table[BUFLEN]; int M, N; struct Edge { int cost, dst; Edge(int d, int c) :dst(d), cost(c) {} }; inline bool fnIsUser(int number) { static int tmp = N - M; return number >= tmp; } list<Edge> nodes[6000]; int moneys[6000]; int fnCount(int node, int bufbase) { table[bufbase] = 0; if(fnIsUser(node)) { table[bufbase + 1] = moneys[node - N + M]; return 1; } else if(nodes[node].size()) { int cntTotalChild = 0; table[bufbase] = 0; for(list<Edge>::iterator it = nodes[node].begin(); it != nodes[node].end(); it++) { int cntNewChild = fnCount(it->dst, bufbase + cntTotalChild + 1); for(int i = 1; i <= cntNewChild; i++) table[bufbase + cntTotalChild + 1 + i] -= it->cost; for(int i = 0; i <= cntTotalChild + cntNewChild; i++) { table[bufbase + cntTotalChild + cntNewChild + 2 + i] = INT_MIN; for(int j = max(i - cntNewChild, 0); j <= cntTotalChild && j <= i; j++) table[bufbase + cntTotalChild + cntNewChild + 2 + i] = max(table[bufbase + j] + table[bufbase + cntTotalChild + 1 + i -j], table[bufbase + cntTotalChild + cntNewChild + 2 + i]); } for(int i = 0; i <= cntTotalChild + cntNewChild; i++) table[bufbase + i] = table[bufbase + cntTotalChild + cntNewChild + 2 + i]; cntTotalChild += cntNewChild; } return cntTotalChild; } return 0; } int main() { while(cin >> N >> M) { for(int i = 0; i < N - M; i++) { int numChild = 0; cin >> numChild; for(int j = 0; j < numChild; j++) { int cost, dst; cin >> dst >> cost; nodes[i].push_back(Edge(dst - 1, cost)); } } for(int i = 0; i < M; i++) cin >> moneys[i]; int ans = fnCount(0, 0); while(table[ans] < 0) ans--; cout << ans << '\n'; } return 0; }