Codeforces Round #127 (Div. 1) C. Fragile Bridges dp

本文解析了CodeForces C.FragileBridges问题,该问题涉及寻找通过脆弱桥梁以获得最高分数的最优路径。文章详细介绍了如何使用动态规划方法解决此问题,并提供了一个实现解决方案的C++代码示例。

C. Fragile Bridges

题目连接:

http://codeforces.com/contest/201/problem/C

Description

You are playing a video game and you have just reached the bonus level, where the only possible goal is to score as many points as possible. Being a perfectionist, you've decided that you won't leave this level until you've gained the maximum possible number of points there.

The bonus level consists of n small platforms placed in a line and numbered from 1 to n from left to right and (n - 1) bridges connecting adjacent platforms. The bridges between the platforms are very fragile, and for each bridge the number of times one can pass this bridge from one of its ends to the other before it collapses forever is known in advance.

The player's actions are as follows. First, he selects one of the platforms to be the starting position for his hero. After that the player can freely move the hero across the platforms moving by the undestroyed bridges. As soon as the hero finds himself on a platform with no undestroyed bridge attached to it, the level is automatically ended. The number of points scored by the player at the end of the level is calculated as the number of transitions made by the hero between the platforms. Note that if the hero started moving by a certain bridge, he has to continue moving in the same direction until he is on a platform.

Find how many points you need to score to be sure that nobody will beat your record, and move to the next level with a quiet heart.

Input

The first line contains a single integer n (2 ≤ n ≤ 105) — the number of platforms on the bonus level. The second line contains (n - 1) integers ai (1 ≤ ai ≤ 109, 1 ≤ i < n) — the number of transitions from one end to the other that the bridge between platforms i and i + 1 can bear.

Output

Print a single integer — the maximum number of points a player can get on the bonus level.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Sample Input

5
2 1 2 1

Sample Output

5

Hint

题意

有n个点,n-1座桥,每座桥最多通过a[i]次,每通过一次可以获得1分

然后问你怎么选择起点和路线,才能获得最多的分数

题解:

dp

我们想想可以发现,我们令l[i]表示i点向左边走,且最后回到i点最多能得多少分,r[i]表示i点向右走,且最后回到i点最多能得多少分

odd[i]表示,从1号桥开始,走到i号桥,最多能得多少分

显然,我们这道题要求的最大值,应该就是l[i]-odd[i]+r[j]+odd[j]这个东西,使得这个东西最大就好了

我们暴力枚举j,然后每次用set去拿到最大的l[i]-odd[i]就好了

应该叫dp吧,大概 O.O

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
long long l[maxn],r[maxn],odd[maxn];
int n;
long long a[maxn];
int get(int x)
{
    if(x%2==1)return x-1;
    return x;
}
set<long long>s;
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n-1;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<n-1;i++)
        if(a[i-1]>1)
            l[i]=l[i-1]+get(a[i-1]);
    for(int i=n-2;i>=0;i--)
        if(a[i]>1)
            r[i]=r[i+1]+get(a[i]);
    for(int i=0;i<n-1;i++)
    {
        odd[i]+=get(a[i]-1)+1;
        if(i>0)odd[i]+=odd[i-1];
    }
    long long ans = l[0]+r[0];
    long long tmp = ans;
    s.insert(l[0]);
    for(int i=1;i<n;i++)
    {
        s.insert(l[i]-odd[i-1]);
        long long p=*--s.lower_bound(1LL*1e16);
        ans=max(r[i]+odd[i-1]+p,ans);
    }
    cout<<ans<<endl;
}

转载于:https://www.cnblogs.com/qscqesze/p/5193580.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值