제출 #619072

#제출 시각아이디문제언어결과실행 시간메모리
619072jophyyjhChase (CEOI17_chase)C++14
70 / 100
334 ms90128 KiB
/** * Notes during contest. * * ------ A ------ * In the example, (3,7,6,6) is the set of optimal pillars to select. Well, I assume * that the subset of pillars shall be connected in order? First, sum all costs of * pillars. The cost of pillars that are used will then be deducted from the total. * Our dp formula is: * dp[k] = min( dp[i] + (h[k] - h[i])^2 - c[k]) * = min( (dp[i] + h[i]^2) - 2h[i] * h[k] ) + (h[k]^2 - c[k]) * This looks like sth that can be solved with dynamic convex hull trick. IMO this * is like the only way to AC this problem. Unfortunately, I don't know how to code * one using std::set<>, nor do I know LiChao tree. Maybe I'll just head to problem * C. * * ------ B ------ * [S1-2] is solvable with a O(n^2) dp (Z-array + dp). I also have a hunch that we * can pass [S3] too (#time_limit = 10s). Oh no... I really suck at str processing * problems... I guess 60 points would be my limit. * * ------ C ------ * Can we score some partials here? Clearly, when Tom visits the route, only the * last node has pigeons, so #pigeons_Tom_meets = #last_node_in_route. OK. Let V be * the set of nodes in the route, so |V| <= v and * #pigeons_Tom_meets = sum{ p_i : i is adjacent to at least one node in V * or i is in V }. * We also know that #pigeons_Jerry_meets = p_i where i is the first node. This means * we can solve [S1-3]. Looks like DFS + dp on tree is good enough to solve the whole * problem! * --------------------------------- After contest --------------------------------- * I totally misunderstood the problem... Took me over an hour in the contest.. The * stuff above is wrong... * * Time Complexity 1: O(n^2) * Time Complexity 2: O(n^2) * Time Complexity 3: O(n^2 * v) * Implementation 0.5 (brute-force first) */ #include <bits/stdc++.h> typedef int64_t int_t; typedef std::vector<int_t> vec; const int_t INF = 0x3f3f3f3f3f3f3f; const int_t N_MAX = 1e5; const int_t V_MAX = 100; int_t n, v; std::vector<vec> tree; vec pigs; // Short form for pigeons. lol int_t dp[N_MAX][V_MAX + 1]; vec adj_sum; int_t search(int_t src) { std::vector<bool> visited(n, false); visited[src] = true; std::queue<int_t> bfs_queue; bfs_queue.emplace(src); dp[src][0] = 0, dp[src][1] = adj_sum[src]; for (int_t i = 2; i <= v; i++) dp[src][i] = -INF; int_t max = 0; while (!bfs_queue.empty()) { int_t t = bfs_queue.front(); bfs_queue.pop(); for (int_t k = 0; k <= v; k++) max = std::max(max, dp[t][k]); for (int_t neighb : tree[t]) { if (!visited[neighb]) { visited[neighb] = true; for (int_t i = 0; i <= v; i++) { dp[neighb][i] = dp[t][i]; if (i > 0) { dp[neighb][i] = std::max(dp[neighb][i], dp[t][i - 1] + adj_sum[neighb] - pigs[t]); } } bfs_queue.emplace(neighb); } } } return max; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); std::cin >> n >> v; tree.assign(n, vec()); pigs.resize(n); for (int_t k = 0; k < n; k++) std::cin >> pigs[k]; for (int_t _ = 0; _ < n - 1; _++) { int_t a, b; std::cin >> a >> b; a--, b--; tree[a].push_back(b); tree[b].push_back(a); } adj_sum.resize(n); for (int_t k = 0; k < n; k++) { adj_sum[k] = 0; for (int_t neighb : tree[k]) adj_sum[k] += pigs[neighb]; } if (n <= 1000) { int_t ans = 0; for (int_t k = 0; k < n; k++) ans = std::max(ans, search(k)); std::cout << ans << '\n'; } else { std::cout << search(0) << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...