传送门: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;
}