打家劫舍小记

经典dp问题

非连续最大数之和

1.线性。

d p [ i ] = m a x ( d p [ i − 1 ] , d p [ i − 2 ] + a [ i ] ) dp[i]=max(dp[i-1],dp[i-2]+a[i]) dp[i]=max(dp[i1],dp[i2]+a[i])

2.环形。

a n s = m a x ( f u n ( 1 , n − 1 ) , f u n ( 2 , n ) ) ans=max(fun(1,n-1),fun(2,n)) ans=max(fun(1,n1),fun(2,n))

f u n ( l , r ) fun(l,r) fun(l,r)即在区间 [ l , r ] [l,r] [l,r]的答案。

3.树形。

即选该结点和不选该结点的最大贡献。

f [ u ] = a [ u ] + g [ l s o n ] + g [ r s o n ] f[u]=a[u]+g[lson]+g[rson] f[u]=a[u]+g[lson]+g[rson]

g [ u ] = m a x ( f [ l s o n ] , g [ l s o n ] ) + m a x ( f [ r s o n ] , g [ r s o n ] ) g[u]=max(f[lson],g[lson])+max(f[rson],g[rson]) g[u]=max(f[lson],g[lson])+max(f[rson],g[rson])

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( n ) O(n) O(n)

其中:线性和环形可以用两个变量来保存 d p [ i − 1 ] , d p [ i − 2 ] dp[i-1],dp[i-2] dp[i1],dp[i2],进行更新即可。

树形可用四个变量保存。

code

//环形
class Solution {
public:
    vector<int>f;
    int solve(vector<int>&a,int l,int r){
        f[l]=a[l],f[l+1]=max(a[l],a[l+1]);
        for(int i=l+2;i<=r;i++)
            f[i]=max(f[i-1],f[i-2]+a[i]);
        return f[r];
    }
    int rob(vector<int>& a) {
        int n=a.size();
        f.resize(n);
        if(n==1) return a[0];
        else if(n==2) return max(a[0],a[1]);
        else return max(solve(a,0,n-2),solve(a,1,n-1));
    }
};
//树形
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    map<TreeNode *,int>f,g;
    int res;
    void dfs(TreeNode *u){
        if(!u) return ;
        dfs(u->left);
        dfs(u->right);
        f[u]=u->val+g[u->left]+g[u->right];
        g[u]=max(f[u->left],g[u->left])+max(f[u->right],g[u->right]);
    }
    int rob(TreeNode* root) {
        dfs(root);
        return max(f[root],g[root]);
    }
};
//
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int dfs(TreeNode* x,int &l,int &r){
        if(!x) return 0;
        int ll,lr,rl,rr;ll=lr=rl=rr=0;
        l=dfs(x->left,ll,lr);
        r=dfs(x->right,rl,rr);
        return max(x->val+ll+lr+rl+rr,l+r);
    }
    int rob(TreeNode* rt) {
        int l=0,r=0;
        return dfs(rt,l,r);
    }
};