Red Playing Cards (牛客多校2 I)

进入博客阅读体验更佳:Red Playing Cards (牛客多校2 I) | 付诺の小站 (funuo0728.github.io)

Red Playing Cards

题目大意


有2n的数组成一个序列,其中1到n每个数都会出现两次。你可以执行以下操作:

选择两个端点相同的区间,删去这个区间,同时获得区间长度 \times 区间端点数的分数。

求所能获得的最大分数为多少。

解题思路


考虑线性DP,f[i]表示只考虑前i个数所能获得的最大分数,思考状态转移:

  • 当[1, i - 1]中没有数与a[i]相同,f[i] = f[i - 1];

  • 当[1, i - 1]中有数与a[i]相同,假设其下标为l,那么状态转移为f[i] = f[l - 1] + g[l][i] + (i - l + 1)\cdot a[i],其中g[i][j]表示这段区间最多能获得的分数比单纯用两端点删掉[l, r]这一区间所获得的分数要大多少;

注意到引入了新的状态,说明这种想法不太可行,但同时g[i][j]也启发我们,只有在区间[i + 1, j - 1]中有两端点大于a[i]的可操作区间,g[i][j]才有值,而如果存在多个这样的可操作区间,就考虑类似01背包的想法,对可操作区间进行操作与不操作的状态转移即可。于是,就想到了重新定义状态:

f[i]表示区间端点为i的区间[l, r]可获得的最大分数,状态转移则对区间[l + 1, r - 1]中的可操作区间对于操作与不操作取个max即可,由于可操作区间的端点一定大于i,所以i应该从大到小进行遍历。

小trick:如果将第0位和第2n + 1位上的数置为0,并考虑f[0],那么f[0]即为最终答案。

具体操作请参考代码。

参考代码

#include <bits/stdc++.h>
#define maxn 6010
#define int long long
using namespace std;
const double eps = 1e-8;
int a[maxn], l[maxn], r[maxn];
​
void solve() {
    int n;  cin >> n;
    n <<= 1;
    for (int i = 1; i <= n; ++i)  cin >> a[i];
    l[0] = 0;  r[0] = n + 1;
    for (int i = 1; i <= n; ++i) {
        if(!l[a[i]])  l[a[i]] = i;
        else  r[a[i]] = i;
    }
    vector<int> f(n / 2 + 1, 0);
    for (int i = n / 2; i >= 0; --i) {
        vector<int>g(n + 2, 0);
        for (int j = l[i] + 1; j < r[i]; ++j) {
            g[j] = max(g[j], g[j - 1] + i);
            if(j == l[a[j]] && r[a[j]] < r[i])  g[r[a[j]]] = max(g[r[a[j]]], g[j - 1] + f[a[j]]);
        }
        f[i] = 2 * i + g[r[i] - 1];
        // cout << i << ": " << f[i] << '\n';
    }
    cout << f[0] << '\n';
}
​
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);  cout.tie(0);
    int t = 1;
    while (t--) {
        solve();
    }
    return 0;
}
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值