Jzoj P6287 扭动的树___记忆化搜索

127 篇文章 0 订阅
78 篇文章 0 订阅

题目大意:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

分析:

因为这颗二叉查找树的中序遍历必定是 k e y key key值的升序排列,
考虑dp,
f i , j , k f_{i,j,k} fi,j,k表示选了区间 [ i , j ] [i,j] [i,j]上的一个点作为 k k k儿子时的最大合法sum和。
显然对于一个区间 [ l , r ] [l,r] [l,r]而言,不管我选出一个什么样的点去作为其父亲的儿子,
都不会影响 f l , r , k f_{l,r,k} fl,r,k
因为代表 [ l , r ] [l,r] [l,r]这个区间的我选出来的儿子,必定是和父亲互质的,且它的父亲是唯一的,
比如 [ l , r ] [l,r] [l,r]区间我选出来的节点假如是作为右儿子,它的父亲必定是 l − 1 l-1 l1这个点,
作为左儿子同理
那么我们用dfs去遍历一遍所有情况即可
注意用 f i , j , k f_{i,j,k} fi,j,k去判断重复出现的情况

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>

#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)

#define N 305

using namespace std;

typedef long long ll;

struct Node {
	ll k, v;
}a[N];
int sum[N][N], ok[N][N], n;
ll f[N][N][2];

bool cmp(Node a, Node b) {
	return a.k < b.k;
}

ll Get_gcd(ll a, ll b) {
	return b ? Get_gcd(b, a % b) : a;
}

ll dfs(int l, int r, int mark) {
	if (l > r) return 0;
	if (f[l][r][mark]) return f[l][r][mark];
	ll now = 0; int fa;
	bool check = 0;
	if (!mark) fa = l - 1; else fa = r + 1;
    rep(i, l, r) {
		if (!ok[fa][i]) continue;
		ll ls = dfs(l, i - 1, 1);
		ll rs = dfs(i + 1, r, 0);
		if (ls == -1 || rs == -1) continue;
		now = max(now, ls + rs);
		check = 1;
	}
	if (!check) return (f[l][r][mark] = - 1);
	return (f[l][r][mark] = now + sum[l][r]);
}

int main(){
	freopen("tree.in", "r", stdin);
	freopen("tree.out","w",stdout);
	scanf("%d", &n);
	rep(i, 1, n) scanf("%lld %lld", &a[i].k, &a[i].v);
	sort(a + 1, a + n + 1, cmp);
	rep(i, 1, n) 
		rep(j, i, n) sum[i][j] = sum[i][j - 1] + a[j].v;
	rep(i, 1, n) {
		ok[0][i] = 1;
		rep(j, i + 1, n)
			if (Get_gcd(a[i].k, a[j].k) != 1) ok[i][j] = ok[j][i] = 1;
    }
	printf("%lld\n", dfs(1, n, 0));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值