怎么正确处理体积为0的物品啊
查看原帖
怎么正确处理体积为0的物品啊
73032
日居月诸lucejx楼主2020/10/25 10:58
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll read() {
	ll x = 0, f = 1; char ch = getchar();
    for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
    for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    return x * f;
}
const int MAXN = 305, MAXM = 305;
const int INF = 0x3f3f3f3f;
struct Edge {
    int v, nxt;
}e[MAXN];
int head[MAXN], cnt;

void addedge(int u, int v) {
    e[++cnt].v = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}
int n, m;
int dp[MAXN][MAXM];//f[i][j]表示在i的子树中选择j科所能得到的最大学分
int s[MAXN];
void dfs(int u) {
    dp[u][0] = 0;
    for(int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        dfs(v);
        for(int j = m; j >= 0; j--)
            for(int k = 0; k <= j; k++)
                dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[v][k]);
        }
    if(u != 0)
        for(int i = m; i >= 1; i--) dp[u][i] = dp[u][i - 1] + s[u];
}
int main() {
    n = read(), m = read();
    for(int i = 0; i < MAXN; i++)
        for(int j = 0; j < MAXM; j++)
            dp[i][j] = -INF;
    for(int i = 1; i <= n; i++) {
        int f = read();
        s[i] = read();
        addedge(f, i);
    }
    dfs(0);
    printf("%d\n", dp[0][m]);
    return 0;
}

在dfs中有一句for(int k = 0; k <= j; k++)

k到底要顺序还是倒序啊。。

我个人觉得是顺序,因为我要更新dp[u][j]的时候,必须保证dp[u][j-k]还没有更新。

如果是倒序的话,那么在k=0的时候,要用到的dp[u][j-k](也就是dp[u][j])早就更新了很多次了,不符合0/1背包的定义

但是蓝书上写的是倒序,是我理解错了还是蓝书这里有点小bug?

谢谢dalao的指导!

2020/10/25 10:58
加载中...