zoukankan      html  css  js  c++  java
  • Apple Tree (可以重复走)

    题目连接:http://poj.org/problem?id=2486

    题意:

    一颗树,n个点,n-1条边,每个点上有一个权值,求从1出发,走k步,最多能遍历到的权值。

    思路:

    很容易想到设dp[x][j]表示x子树分配j步能获得最多苹果数量,但是这样是不够的,因为很容易发现只有哪些回到了x点的方案的代价才是子树大小*2,但是走到最后的时候其实可以不用回到x点。

    那么我们就增加状态纬度,设dp[i][j][0/1]:给树i恰好分配j步(回/不回来)i点的最大值。然后分3中情况写状态转移方程:

    dp[x][j][0]=max(dp[x][j][0],dp[x][j-k][0]+dp[y][k-2][0]);   //情况①:表示遍历从左边的子树回来x点之后,去y子树,再回来x点。

    dp[x][j][1]=max(dp[x][j][1],dp[x][j-k][0]+dp[y][k-1][1]);  //情况②:表示从左边回来,去y子树,不回来x点了

    dp[x][j][1]=max(dp[x][j][1],dp[x][j-k][1]+dp[y][k-2][0]);  //情况3:表示从y子树回来,去左边,不回来x点了

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define ls nod<<1
    #define rs (nod<<1)+1
    
    const double eps = 1e-10;
    const int maxn = 100 + 10;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    struct edge {
        int v,nxt;
    }e[maxn<<1];
    
    int head[maxn];
    int cnt;
    int f[maxn][maxn<<1][2];
    int n,m;
    
    inline void add_edge(int u,int v) {
        e[++cnt].v = v;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    
    inline void dfs(int x,int fa) {
        for (int i = head[x];~i;i = e[i].nxt) {
            int v = e[i].v;
            if (v == fa)
                continue;
            dfs(v,x);
            for (int j = m;j >= 1;j--) {
                for (int k = 0;k <= j;k++) {
                    if (k>=2) f[x][j][0]=max(f[x][j][0],f[x][j-k][0]+f[v][k-2][0]);
                    if (k>=1) f[x][j][1]=max(f[x][j][1],f[x][j-k][0]+f[v][k-1][1]);
                    if (k>=2) f[x][j][1]=max(f[x][j][1],f[x][j-k][1]+f[v][k-2][0]);
                }
            }
        }
    }
    
    int main() {
        while (cin >> n >> m) {
            cnt = 0;
            memset(head,-1, sizeof(head));
            memset(f,-0x3f, sizeof(f));
            for (int i = 1;i <= n;i++) {
                int val;
                cin >> val;
                f[i][0][1] = f[i][0][0] = val;
            }
            for (int i = 1;i < n;i++) {
                int u,v;
                cin >> u >> v;
                add_edge(u,v);
                add_edge(v,u);
            }
            dfs(1,0);
            int ans=0;
            for (int i=0;i<=m;i++)
                ans=max(ans,max(f[1][i][0],f[1][i][1]));
            cout << ans << endl;
        }
        return 0;
    }
  • 相关阅读:
    还原 | revert (Cascading & Inheritance)
    过滤器 | filter (Filter Effects)
    过渡时间 | transition-duration (Animations & Transitions)
    过渡延时 | transition-delay (Animations & Transitions)
    过渡属性 | transition-property (Animations & Transitions)
    过渡定时功能 | transition-timing-function (Animations & Transitions)
    过渡 | transition (Animations & Transitions)
    ProxySQL 读写分离
    《抛弃learning rate decay吧!》
    《Tensorflow 中 learning rate decay 的奇技淫巧 》
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12363346.html
Copyright © 2011-2022 走看看