Codeforces Round #127 (Div. 2) C - Fragile BridgesCodeforces

C. Fragile Bridges
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 ≤ 1091 ≤ i < n) — the number of transitions from one end to the other that the bridge between platforms i and i + 1can 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 cincout streams or the %I64dspecifier.

Sample test(s)
input
5
2 1 2 1
output
5
Note

One possibility of getting 5 points in the sample is starting from platform 3 and consequently moving to platforms 4321 and 2. After that the only undestroyed bridge is the bridge between platforms 4 and 5, but this bridge is too far from platform 2 where the hero is located now.


有N个点,点与点之间存在通过次数被限定的桥,每通过一次桥,能获得一分,问你最多能获得多少分(起点自己决定)
解析:从左边DP一次起,右边DP一次,dp [i][0]从i点出发遍历0 - i 点不回来,dp [i][1]表示从i点出发遍历0 - i 点而且回来


#include<iostream>  
#include<cstdio>  
#define max(a,b) ((a)>(b)?(a):(b))  
using namespace std;  
typedef __int64 ll;  
const int N = 100005;  
int num[N];  
ll dpl[N][2], dpr[N][2];  
int main(){  

    int n,i;  
    cin >> n;  
    for( i=0;i<n-1;i++)  
        scanf("%d",&num[i]);  
    dpl[0][0] = dpl[0][1] = 0;  
   
	//关键是给dp[i][j]的i,j下好定义,这里的j只取0/1,表示最终遍历完0-i后能不能回到i点,0就不能,1就可以
	
	for( i=1;i<n;i++){  // num[i-1]/2*2 是为了消除奇数的影响,使得奇偶数时的情况一样,最终得到一个偶数,那么才能从i-1到i
						// 至于是dpl[i-1][1]就是要从i-1到i,其实就是说i-1的时候能回到本身,就能从i-1开始了;
        dpl[i][1] = (num[i-1] > 1 ? num[i-1]/2*2 + dpl[i-1][1] : 0);  //  取零是因为没有路可走了
        if(num[i-1] & 1) dpl[i][0] =max( dpl[i-1][1] + num[i-1], dpl[i-1][0] + num[i-1]) ;  // 注意是从i点出发的,所以只要通过
        else dpl[i][0] = max( dpl[i - 1][1] + num[i - 1] - 1, dpl[i-1][0] + num[i-1] -1);	//路径的次数是奇数,就绝对回不来
    }									//如果路径的通过次数是一个偶数,想要不回来很简单,减去一就是了。

    dpr[n-1][0] = dpr[n-1][1] = 0;  
    for( i=n-2;i>=0;i--){  
        dpr[i][1] = (num[i] > 1 ? num[i]/2*2 + dpr[i+1][1] : 0);  
        if(num[i] & 1) dpr[i][0] = max( dpr[i + 1][1]  + num[i],num[i] + dpr[i+1][0]);  
        else dpr[i][0] = max(dpr[i + 1][1] + num[i] - 1, dpr[i+1][0] + num[i]-1);  
    }  
    ll ans = 0;  
    for( i=0; i<n;i++){  
    //  printf("I:%d    L0:%lld     L1:%lld      R0:%lld    R1:%lld\n",i,dpl[i][0],dpl[i][1],dpr[i][0],dpr[i][1]);  
        ll a = max(dpl[i][0],dpr[i][0]);  
        ll b = max(dpl[i][1]+dpr[i][0],dpr[i][1]+dpl[i][0]);  
        ans = max(ans,max(a,b));  
    }  
    printf("%I64d\n",ans);  
}  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值