一种只用一个状态的做法
查看原帖
一种只用一个状态的做法
1022282
Jefferyz楼主2024/7/25 14:29

记fi,j,kf_{i,j,k}为距离ii点最近的祖先或ii点本身的点为jj,在ii点与ii的子树中共设立kk个伐木场的最小代价。

转移如下:

for (int i = 0; i <= n; ++i) {
        if (dis[i][x] != -1 && dis[i][x]) f[x][i][0] = a[x] * dis[i][x];
        f[x][x][1] = 0;
        if (!x) f[x][x][0] = 0;
    }
    for (int i = head[x]; ~i; i = e[i].next) {
        int y = e[i].v;
        dp(y);
        for (int j = 0; j <= n; ++j) {
            if (dis[j][x] == -1) continue;
            for (int l = k; l >= 0; --l) {
                if (f[x][j][l] < inf && f[y][j][0] < inf) f[x][j][l] = f[x][j][l] + f[y][j][0];
                if (f[x][j][l] < inf && f[y][y][0] < inf) f[x][j][l] = f[x][j][l] + f[y][y][0];
                for (int m = 1; m <= l; ++m) {
                    if (f[x][j][l - m] < inf && min(f[y][j][m], f[y][y][m]) < inf)
                        f[x][j][l] = min(f[x][j][l],
                                         f[x][j][l - m] +
                                         min(f[y][j][m],
                                             f[y][y][m]));
                }
            }
        }
    }
2024/7/25 14:29
加载中...