zoukankan      html  css  js  c++  java
  • 树上背包小结

    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;
        }
    
    

    待补充

  • 相关阅读:
    [导入]微软的XP和Server2003在双核CPU上有缺陷
    [导入]可怜的软件开发
    [CZoneSoft]在Firefox里播放wmv流媒体视频
    [导入]直接用IL改写别人的程序
    [导入]清除3721的中文上网插件CNS
    [导入]完成可脚本调用的视频录制控件
    垃圾短信投诉的地方和方法
    [导入]不需要服务器端的在线录制视频
    [导入]各银行跨行提款收费比较
    [导入]电热水器选购
  • 原文地址:https://www.cnblogs.com/hfcdyp/p/13655059.html
Copyright © 2011-2022 走看看