P2014 [CTSC1997]选课
没有变形的树上背包
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#define LL long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f
#define PI 3.1415926535898
#define F first
#define S second
#define endl '
'
#define lson rt << 1
#define rson rt << 1 | 1
#define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int maxn = 307;
const int mod = 1e9 + 7;
int n, m;
int dp[maxn][maxn];
vector<int> G[maxn];
void work(int u)
{
f(i, 0, G[u].size())
{
int v = G[u][i];
work(v);
for (int j = m + 1; j >= 1; j--)
{
for (int k = 0; k < j; k++) dp[u][j] = max(dp[u][j], dp[v][k] + dp[u][j - k]);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
int fa;
_rep(i, 1, n)
{
cin >> fa >> dp[i][1];
G[fa].push_back(i);
}
work(0);
cout << dp[0][m + 1] << endl;
}
P1273 有线电视网
(dp[u][v]) 表示以u为根选取v个节点的最大收益,收益为正时表示可行
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define LL long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f
#define PI 3.1415926535898
#define F first
#define S second
#define endl '
'
#define lson rt << 1
#define rson rt << 1 | 1
#define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int maxn = 3e3 + 7;
const int mod = 1e9 + 7;
int n, m;
int w[maxn];
int dp[maxn][maxn];
vector<pair <int, int> > G[maxn];
int dfs(int u)
{
if (u > n - m)
{
dp[u][1] = w[u];
return 1;
}
int leaf = 0;
f(i, 0, G[u].size())
{
int v = G[u][i].F;
int cst = G[u][i].S;
int tmp = dfs(v);
leaf += tmp;
for(int j = leaf; j > 0; j--)
{
_rep(k, 0, tmp)
{
if (j - k < 0) break;
dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[v][k] - cst);
}
}
}
return leaf;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
int cnt, x, y;
memset(dp, -inf, sizeof(dp));
_rep(i, 1, n) dp[i][0] = 0;
_rep(i, 1, n - m)
{
cin >> cnt;
_rep(j, 1, cnt)
{
cin >> x >> y;
G[i].push_back({ x, y });
}
}
_rep(i, n - m + 1, n)
{
cin >> w[i];
}
dfs(1);
for (int i = m; i >= 0; i--)
{
if (dp[1][i] >= 0)
{
cout << i << endl;
break;
}
}
}
POJ2486
(dp[u][j][1]) 表示从u开始走l步不回到u的最大收益,对某个子节点v考虑两种情况,经过u的其它子节点最后到v的任意子节点;经过v的子树后回到u,再到其它子节点。
(dp[u][j][0]) 表示从u开始走l步回到u的最大收益,从同状态的子节点转移。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define LL long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f
#define PI 3.1415926535898
#define F first
#define S second
#define endl '
'
#define lson rt << 1
#define rson rt << 1 | 1
#define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int maxn = 107;
const int maxm = 207;
const int mod = 1e9 + 7;
int n, k;
int w[maxn];
int dp[maxn][maxm][2];
vector<int> G[maxn];
int dfs(int u, int f)
{
dp[u][0][1] = dp[u][0][0] = w[u];
for (int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if (v == f) continue;
dfs(v, u);
for (int j = k; j >= 1; j--)
{
for (int l = 0; l <= j - 1; l++)
{
dp[u][j][1] = max(dp[u][j][1], dp[u][j - l - 1][0] + dp[v][l][1]);
if (l <= j - 2)
{
dp[u][j][1] = max(dp[u][j][1], dp[u][j - l - 2][1] + dp[v][l][0]);
dp[u][j][0] = max(dp[u][j][0], dp[u][j - l - 2][0] + dp[v][l][0]);
}
}
}
}
return 0;
}
int main()
{
while (cin >> n >> k)
{
int x, y;
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++)
{
cin >> x;
w[i] = x;
G[i].clear();
}
for (int i = 1; i <= n - 1; i++)
{
cin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1, -1);
int ans = 0;
for (int i = 0; i <= k; i++) ans = max(ans, max(dp[1][i][1], dp[1][i][0]));
cout << ans << endl;
}
待补充