经典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[i−1],dp[i−2]+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,n−1),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[i−1],dp[i−2],进行更新即可。
树形可用四个变量保存。
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);
}
};