1 2 3 4

[HNOI/AHOI2018] 道路

https://www.luogu.com.cn/problem/P4438

这个神仙问题告诉我们,树形dp还是dp,动态规划是真的难,不会设转移方程要吃大亏

 

 写成记忆话搜索是真的方便,服了

 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 22000;
ll INF = 1e16;
int n;

//-----------------建立边部分

ll dp[22000][44][44];
ll a[22000], b[22000], c[22000];
int son[22000][3];


ll dfs(int x, int i, int j) {
	if (x < 0) {
		int xx = -x;
		return 1LL*c[xx] * (a[xx] + i)*(b[xx] + j);
	}
	if (dp[x][i][j] < INF) return dp[x][i][j];

	return dp[x][i][j] = min(dfs(son[x][0], i, j) + dfs(son[x][1], i, j + 1), dfs(son[x][0], i+1, j) + dfs(son[x][1], i, j));
}

int main() {
	for (int i = 0; i < maxn; i++) {
		for (int j = 0; j < 44; j++) {
			for (int k = 0; k < 44; k++) {
				dp[i][j][k] = INF;
			}
		}
	}

	scanf("%d", &n);
	int be, en;
	for (int i = 1; i < n; i++) {
		scanf("%d%d", &be, &en);
		son[i][0] = be;
		son[i][1] = en;
	}
	for (int i = 1; i <= n; i++) {
		scanf("%lld%lld%lld", &a[i], &b[i], &c[i]);
	}
	int root = 1;
	ll ans = dfs(root, 0, 0);
	cout << ans << endl;
	return 0;
}

  

posted @ 2020-03-18 19:20  Lesning  阅读(140)  评论(0编辑  收藏  举报