發現商品間的關係顯然是棵樹,所以做樹上揹包。
發現商品的**都很高不能放在狀態裡,而價值都是1,所以轉換維度。
定義\(dp[u][j][0/1]\)為在\(u\)的子樹中選出\(j\)個物品所需要的最小**,其中0代表不用優惠券買u,1代表用優惠券買u。
轉移:\[\sum_^
\]\[\sum_^
\]\[dp[u][j + k][1] = min(dp[u][j + k][1], dp[u][j][1] + min(dp[v][k][1], dp[v][k][0]))
\]\[dp[u][j + k][0] = min(dp[u][j + k][0], dp[u][j][0] + dp[v][k][0])
\]答案為 \(max(i)\) 滿足 \(dp[1][i][1] <= b\)
#include #include #include #include using namespace std;
char buf[1 << 20], *p1 = buf, *p2 = buf;
char getc()
return *p1++;
}inline int read()
while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getc();
return s * w;
}const int maxn = 5e3 + 5;
int n, b;
struct edge e[maxn * maxn];
int head[maxn], tot;
void add(int u, int v) ;
head[u] = tot;
}int dp[maxn][maxn][3];
int siz[maxn], c[maxn], d[maxn];
void dfs(int u)
return;
}void dp(int u)
} }
}int main()
else
}dfs(1);
memset(dp, 0x3f, sizeof dp);
for (int i = 1; i <= n; i++)
dp(1);
int ans;
for (int i = 1; i <= n; i++)
printf("%d\n", ans);
return 0;
}
另外,兩個dfs可以合起來寫,這樣就相當於一次列舉一條邊的兩個端點,從各自的子樹中去選擇。
#include #include #include #include using namespace std;
char buf[1 << 20], *p1 = buf, *p2 = buf;
char getc()
return *p1++;
}inline int read()
while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getc();
return s * w;
}const int maxn = 5e3 + 5;
int n, b;
struct edge e[maxn * maxn];
int head[maxn], tot;
void add(int u, int v) ;
head[u] = tot;
}int dp[maxn][maxn][3];
int siz[maxn], c[maxn], d[maxn];
void dp(int u)
} siz[u] += siz[v];
}}int main()
else
}//dfs(1);
memset(dp, 0x3f, sizeof dp);
for (int i = 1; i <= n; i++)
dp(1);
int ans;
for (int i = 1; i <= n; i++)
printf("%d\n", ans);
return 0;
}
可憐與超市
t4 可憐與超市 long long 我看到10的九次方了,我直接龍龍 不對啊,b也小於10億啊,int就夠了 我聰明的大腦瞬間看出,樹形dp 題幹的意思是不是1就是根?應該是,但我覺得不穩 f u 0 1 以u為根的子樹,u買或者不買的能購買的最多商品 最優解 之所以這麼定義因為跑不了10億乘50...
樹上揹包練習
p2014 ctsc1997 選課 p2014 ctsc1997 選課 solution 樹上揹包模板題 因為有多節課是沒有先修課的,所以並不是只有一棵樹,用乙個0號點作為沒有先修課的課程的先修課,這樣就合併成了一棵樹,只要選取m 1個點 必選0 即可。轉移方程 dp u j max dp u j ...
01揹包 可憐的波特
哈里波特在姨夫家遭受非人待遇,他被迫做很多事。有一次,姨夫有給了他一大堆家務。哈里知道每件做完家務的時間,重要程度,還知道總時間與任務總數,他必須盡量合理的安排使他在規定時間內完成的重要程度最大。第一行,t,m t,m 10000 表示哈里波特的時間和姨夫要他做的家務數。接下來m行,每行2個值表示該...