bzoj1495 [NOI2006] network charges complexity analysis tree backpack +

Topic Portal

https://lydsy.com/JudgeOnline/problem.php?id=1495

answer

Can be found by observing, for a \ (LCA \) , if the \ (nA \ Leq nB of \) , then the equivalent of all options \ (A \) to have to pay \ (f [i] [j ] \) of cost. In this way we can easily pre-out if a leaf in a \ (LCA \) the cost when choosing a less kind of payment should be paid for and at.

Then consider dp. Order \ (dp [x] [i ] \) of \ (X \) is the root of the subtree, \ (I \) a first leaf selected minimum total cost payment method, and then the backpack can be combined transfer.

But we can see that the contribution of each leaf depends on all of its ancestors \ (nA \) and \ (nB \) the size of the relationship. This does not meet the general dp no after-effect of.

I then there is no way to begin autistic.

After a long, have read about the solution to a problem, that may be a non-violent enumerate the circumstances of each leaf, the complexity can be guaranteed.

Complexity is probably \ (T (m) = a 4T (\ FRAC M2) + O (m ^ 2) \) . The master theorem, \ (m ^ 2 = m ^ {\ log_2 ^. 4} = m ^ 2 \) , so the total time complexity is \ (m ^ 2 \ log m = m ^ 2n = n ^ {2n} n \) .

This story tells us analyze the time complexity is still very important, looks very fake a practice may actually be right, attention should distinguish the correctness of the algorithm, do not be fooled by superficial phenomena.


code show as below:

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

#define lc x << 1
#define rc x << 1 | 1

const int N = 2048 + 7;
const int INF = 0x7f7f7f7f;

int n, m;
int a[N], c[N], f[N][N], w[N][N], col[N], dp[N][N];

inline void dfs(int x) {
    if (x >= m) {
        if (a[x - m + 1]) dp[x][0] = c[x - m + 1], dp[x][1] = 0;
        else dp[x][0] = 0, dp[x][1] = c[x - m + 1];
        for (int i = x >> 1; i; i >>= 1) dp[x][col[i] ^ 1] += w[x][i];
        return;
    }
    int siz = 1 << (n - std::__lg(x));
    memset(dp[x], 0x7f, sizeof(int) * (siz + 1));
    col[x] = 0, dfs(lc), dfs(rc);
    for (int i = 0; i <= (siz >> 1); ++i)
        for (int j = 0; i + j <= (siz >> 1); ++j)
            smin(dp[x][i + j], dp[lc][i] + dp[rc][j]);
    col[x] = 1, dfs(lc), dfs(rc);
    for (int i = 0; i <= (siz >> 1); ++i)
        for (int j = (siz >> 1) - i + 1; j <= (siz >> 1); ++j)
            smin(dp[x][i + j], dp[lc][i] + dp[rc][j]);
}

inline void ycl() {
    for (int i = 1; i <= m; ++i) {
        for (int j = i + 1; j <= m; ++j) {
            int x = i + m - 1, y = j + m - 1, lca = x >> (std::__lg(x ^ y) + 1);
            w[x][lca] += f[i][j], w[y][lca] += f[i][j];
        }
    }
}

inline void work() {
    ycl();
    dfs(1);
    int ans = INF;
    for (int i = 0; i <= m; ++i) smin(ans, dp[1][i]);
    printf("%d\n", ans);
}

inline void init() {
    read(n), m = 1 << n;
    for (int i = 1; i <= m; ++i) read(a[i]);
    for (int i = 1; i <= m; ++i) read(c[i]);
    for (int i = 1; i <= m; ++i)
        for (int j = i + 1; j <= m; ++j)
            read(f[i][j]), f[j][i] = f[i][j];
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/bzoj1495.html