답안 #619072

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
619072 2022-08-02T09:41:36 Z jophyyjh Chase (CEOI17_chase) C++14
70 / 100
334 ms 90128 KB
/**
 * 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';
    }
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 324 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 332 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 324 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 332 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 326 ms 1212 KB Output is correct
8 Correct 42 ms 1200 KB Output is correct
9 Correct 32 ms 1228 KB Output is correct
10 Correct 334 ms 1208 KB Output is correct
11 Correct 145 ms 1204 KB Output is correct
12 Correct 63 ms 1200 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 161 ms 89156 KB Output is correct
2 Correct 134 ms 89084 KB Output is correct
3 Correct 102 ms 90128 KB Output is correct
4 Correct 109 ms 89228 KB Output is correct
5 Correct 177 ms 89192 KB Output is correct
6 Correct 188 ms 89220 KB Output is correct
7 Correct 182 ms 89172 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 324 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 332 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 326 ms 1212 KB Output is correct
8 Correct 42 ms 1200 KB Output is correct
9 Correct 32 ms 1228 KB Output is correct
10 Correct 334 ms 1208 KB Output is correct
11 Correct 145 ms 1204 KB Output is correct
12 Correct 63 ms 1200 KB Output is correct
13 Correct 161 ms 89156 KB Output is correct
14 Correct 134 ms 89084 KB Output is correct
15 Correct 102 ms 90128 KB Output is correct
16 Correct 109 ms 89228 KB Output is correct
17 Correct 177 ms 89192 KB Output is correct
18 Correct 188 ms 89220 KB Output is correct
19 Correct 182 ms 89172 KB Output is correct
20 Incorrect 183 ms 89160 KB Output isn't correct
21 Halted 0 ms 0 KB -