Educational Codeforces Round 137 (Rated for Div. 2) C. Save the Magazines 解题报告

原题链接:

Problem - 1743C - Codeforces

题目描述:

Monocarp has been collecting rare magazines for quite a while, and now he has decided to sell them. He distributed the magazines between nn boxes, arranged in a row. The ii-th box contains aiai magazines. Some of the boxes are covered with lids, others are not.

Suddenly it started to rain, and now Monocarp has to save as many magazines from the rain as possible. To do this, he can move the lids between boxes as follows: if the ii-th box was covered with a lid initially, he can either move the lid from the ii-th box to the box (i−1)(i−1) (if it exists), or keep the lid on the ii-th box. You may assume that Monocarp can move the lids instantly at the same moment, and no lid can be moved more than once. If a box will be covered with a lid after Monocarp moves the lids, the magazines in it will be safe from the rain; otherwise they will soak.

You have to calculate the maximum number of magazines Monocarp can save from the rain.

Input

The first line contains a single integer tt (1≤t≤1041≤t≤104) — the number of the testcases.

The first line of each testcase contains a single integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of boxes.

The second line contains a string of nn characters 0 and/or 1. If the ii-th character is 1, the ii-th box is initially covered with a lid. If the ii-th character is 0, the ii-th box is initially not covered.

The third line contains a sequence of integers a1,a2,…,ana1,a2,…,an (1≤ai≤1041≤ai≤104), where aiai is the number of magazines in the ii-th box.

The sum of nn over all testcases doesn't exceed 2⋅1052⋅105.

Output

For each testcase, print one integer — the maximum number of magazines Monocarp can save from the rain.

题目大意:

给定了n个盒子,盒子内各有ai本书,再给定一个字符串s,si=0表示ai上面没有盖子,1表示有盖子,可以把有盖子的左移一格(第一个严格来说不可以左移),问盖住的盒子里书的数量最大和。

解题思路:

有无后效性和最优子结构性质并且拥有重叠子问题,所以可以使用动态规划解决:

dp[i][0]表示第i个盖子不左移的情况下,前i个盒子能获得的最大值,

dp[i][1]表示第i个盖子左移的情况下,前i个盒子能取得的最大值,

状态转移:

当第i个盒子没有盖子,也就是f[i]=0时,dp[i][0]和dp[i][1]都将继承dp[i-1][0]和dp[i-1][1]之间的较大者。

当第i个盒子上有盖子,也就是f[i]=1时,dp[i][0]为a[i]加上dp[i-1][0]和dp[i-1][1]之间的较大者,

p[i][1]为a[i-1]加上dp[i-1][1],为什么不考虑dp[i-1][0],因为这一位要移动,那么前一位肯定也要移动

代码(CPP):

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef unsigned long long ull;
const int maxn = 2e5 + 10;
const int INF = 0x3fffffff;
int dp[maxn][2], f[maxn], a[maxn], n, m;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << fixed;
    cout.precision(18);

    int t;
    cin >> t;
    while (t--)
    {
        cin >> n;
        string s;
        cin >> s;
        s = " " + s;
        for (int i = 1; i <= n; i++)
        {
            if (s[i] == '0')
                f[i] = 0;
            else
                f[i] = 1;
        }

        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            dp[i][0] = dp[i][1] = 0;
        }

        for (int i = 1; i <= n; i++)
        {
            dp[i][0] = dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]);
            if(f[i])
            {
                dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]) + a[i];
                dp[i][1] = dp[i - 1][1] + a[i - 1];
            }
        }
        cout << max(dp[n][0], dp[n][1]) << endl;
    }
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值