HDU - 5900 QSC and Master 区间DP

本文介绍了一种使用区间动态规划解决涉及数学运算(如求最大得分)的问题的方法。通过两个N立方级别的区间DP过程,首先判断任意连续区间内的元素是否可以被消除,然后找出能够获得的最大得分。

传送门:HDU5900

题意:给出n 个pair<int , int>,每次可以选择相邻的两个pair。如果他们的first不互质就可以把它们都删掉,并且获得second之和的分数,问最大得分是多少

思路:先n^3区间dp求出任意一段连续区间能否消掉,用f[i][j]表示,再n^3区间dp取一个最大值。转移很简单,代码里一看就懂。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
typedef pair<int,int> P;
const int MAXN = 100010;
bool f[303][303];
ll dp[303][303], key[303], val[303];
int main()
{
	int T, n;
	cin >> T;
	while(T--)
	{
		memset(f, 0, sizeof(f));
		memset(dp, 0, sizeof(dp));
		cin >> n;
		for(int i = 1; i <= n; i++)
		{
			scanf("%lld", key + i);
			if(i > 1 && __gcd(key[i], key[i - 1]) > 1)
			f[i - 1][i] = 1;
		}
		for(int i = 1; i <= n; i++)
		scanf("%lld", val + i);
		for(int len = 4; len <= n; len += 2)
		{
			for(int l = 1, r = l + len - 1; r <= n; l++, r++)
			{
				if(__gcd(key[l], key[r]) > 1)
				f[l][r] |= f[l + 1][r - 1];
				for(int mid = l + 1; mid < r && !f[l][r]; mid++)
				f[l][r] |= f[l][mid] & f[mid + 1][r];
			}
		}
		for(int len = 2; len <= n; len += 2)
		{
			for(int l = 1, r = l + len - 1; r <= n; l++, r++)
			{
				dp[l][r] = dp[l + 1][r - 1];
				if(f[l][r]) dp[l][r] += val[l] + val[r];
				for(int mid = l + 1; mid < r; mid++)
				dp[l][r] = max(dp[l][r], dp[l][mid] + dp[mid + 1][r]);
			}
		}
		ll ans = 0;
		for(int i = 1; i <= n; i++)
		for(int j = 1; j <= n; j++)
		ans = max(ans, dp[i][j]);
		cout << ans << endl;
	}
 	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值