【DP】【树形DP】

保安站岗

#include<bits/stdc++.h> 
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
const int maxn = 4e3 + 3;
int val[maxn], to[maxn], nx[maxn], hd[maxn], cnt = 0;
int f[maxn][4];
void add(int u, int v) {
	++cnt;
	to[cnt] = v;
	nx[cnt] = hd[u];
	hd[u] = cnt;
}
void dfs(int u, int fa) {
	int pt = 0, sum = INT_MAX;
	f[u][0] = val[u];
	for(int i = hd[u]; i; i = nx[i]) {
		int v = to[i];
		if(v != fa) {
			dfs(v, u);
			f[u][0] += min(f[v][0], min(f[v][1], f[v][2]));
			f[u][2] += min(f[v][0], f[v][1]);
			if(f[v][0] <= f[v][1]) {
				pt = 1;
				f[u][1] += f[v][0];
			}
			else {
				f[u][1] += f[v][1];
				sum = min(sum, f[v][0]-f[v][1]);
			}
		}
	}
	if(!pt) {
		f[u][1] += sum;
	}
}
int main() {
	int t, n, k, m, x;
	scanf("%d", &t);
	rep(i, 1, t) {
		scanf("%d%d%d", &n, &m, &k);
		val[n] = m;
		while(k--) {
			scanf("%d", &x);
			add(n, x);
			add(x, n);
		}
	}
	dfs(1, 0);
	printf("%d", min(f[1][0], f[1][1]));
	return 0;
}

有线电视网

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=3e3+3;
int n,m,cnt=0;
int hd[maxn],nx[maxn],cost[maxn],gain[maxn],to[maxn];
int f[maxn][maxn],num[maxn];
void dfs(int u) {
	f[u][0] = 0;
	for(int i=hd[u]; i; i=nx[i]) {
		int v=to[i];
		dfs(v);
		num[u] += num[v];
		for(int j = num[u]; j > 0; --j) {
			for(int k = 1; k <= min(j, num[v]); ++k) {
				f[u][j] = max(f[u][j], f[u][j-k] + f[v][k] - cost[i]);
			}
		}
	}
	if(u > n-m) {
		num[u] = 1;
		f[u][1] = gain[u];
	}
}
void add(int u,int v,int w) {
	++cnt;
	to[cnt]=v;
	cost[cnt]=w;
	nx[cnt]=hd[u];
	hd[u]=cnt;
}
int main() {
	scanf("%d%d",&n,&m);
	memset(f, 128, sizeof f);
	rep(i,1,n - m) {
		int k;
		scanf("%d",&k);
		while(k--) {
			int v,w;
			scanf("%d%d", &v, &w);
			add(i,v,w);
		}
	}
	rep(i,n-m+1,n) scanf("%d", &gain[i]);
	dfs(1);
	for(int i = m; i >= 0 ; --i) {
		if(f[1][i] >= 0) {
			cout << i << endl;
			break;
		}
	}
	return 0;
}

打家劫舍3

/**
 * 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 dp[10005][2]={0};
    int cnt=0;
    int dfs(TreeNode* root){
        if(!root) return 0;
        int x=++cnt;
        int lf=dfs(root->left);
        int rf=dfs(root->right);
        dp[x][0]=max(dp[lf][0],dp[lf][1])+max(dp[rf][0],dp[rf][1]);
        dp[x][1]=dp[lf][0]+dp[rf][0]+root->val;
        return x;
    }
    int rob(TreeNode* root) {
        dfs(root);
        return max(dp[1][0],dp[1][1]);
    }
};

空间优化的

/**
 * 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:
    void dfs(TreeNode* root,int &dp1,int &dp2){
        if(!root){
            dp1=dp2=0;
            return ;
        }
        int lf1,lf2,rf1,rf2;
        dfs(root->left,lf1,lf2);
        dfs(root->right,rf1,rf2);
        dp1=max(lf1,lf2)+max(rf1,rf2);
        dp2=lf1+rf1+root->val;
        return ;
    }
    int rob(TreeNode* root) {
        int dp1,dp2;
        dfs(root,dp1,dp2);
        return max(dp1,dp2);
    }
};

最大子树和

#include<bits/stdc++.h>
#define rep(i,a,b) for(ll i=a;i<=b;++i)
using namespace std;
typedef long long ll;

const ll maxn=4e4+5;
ll to[maxn],nx[maxn],hd[maxn],b[maxn];

ll cnt=0,mx=INT_MIN,num[maxn];
void add(ll u,ll v){
	++cnt;
	to[cnt]=v;
	nx[cnt]=hd[u];
	hd[u]=cnt;
}
void dfs(ll u,ll f){
	num[u]=b[u];

	for(ll i=hd[u];i;i=nx[i]){
		ll v=to[i];
		if(v!=f){
			dfs(v,u);
			num[u]+=num[v];
		} 
	}
	
	if(num[u]<0)
		num[u]=0;
	mx=max(mx,num[u]);
}
int main(){
	ll n;
	scanf("%lld",&n);

	rep(i,1,n) scanf("%lld",&b[i]);

	rep(i,1,n-1){
		ll u,v;
		scanf("%lld%lld",&u,&v);

		add(u,v);

		add(v,u);

	}
	dfs(1,0);
	cout << mx;
	return 0;
}

重建道路

#include<bits/stdc++.h> 
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=500;
int n,p;
int to[maxn],nx[maxn],hd[maxn];
int c[maxn],dp[maxn][maxn],cnt=0,ans=INT_MAX;
void add(int u,int v){
	c[u]++;
	++cnt;
	to[cnt]=v;
	nx[cnt]=hd[u];
	hd[u]=cnt;
}
void dfs(int u,int fa){
	dp[u][1]=c[u];
	for(int i=hd[u];i;i=nx[i]){
		int v=to[i];
		if(v!=fa){
			dfs(v,u);
			for(int j=p;j>=1;--j){
				for(int k=1;k<j;++k){
					dp[u][j]=min(dp[u][j],dp[u][k]+dp[v][j-k]-2);
				}
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&p);
	rep(i,1,n-1){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	memset(dp,0x3f,sizeof dp);
	dfs(1,0);
	rep(i,1,n) ans=min(ans,dp[i][p]);
	cout << ans;
	return 0;
}

有依赖的背包问题

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e2 + 2;
int v[maxn], w[maxn], to[maxn], nx[maxn], hd[maxn], cnt = 0;
int N, V, c, f[maxn][maxn];
void add(int u, int v) {
	++cnt;
	to[cnt] = v;
	nx[cnt] = hd[u];
	hd[u] = cnt;
}
void dfs(int u) {
	for(int i = v[u]; i <= V; ++i) {
		f[u][i] = w[u];
	}
	for(int i = hd[u]; i ; i = nx[i]) {
		dfs(to[i]);
		for(int j = V; j >= v[u]; --j) {
			for(int k = 0; k <= j - v[u] ; ++k) {
				f[u][j] = max(f[u][j], f[u][j - k] + f[to[i]][k]);
			}
		}
	}
}
int main() {
	int rt = 1;
	cin >> N >> V;
	for (int i = 1; i <= N; ++i) {
		cin >> v[i] >> w[i] >> c;
		if(c != -1) {
			add(c, i);
		}
		else rt = i;
	}
	dfs(rt);
	cout << f[rt][V];
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值