Yahoo Programming Contest 2019 D-Ears

传送门

题目大意

分析

我们不难整个线段可以被划分为5段

我们设路径到达的最左的地方是L,最右的地方是R

则这五段分别是0~L,L+1~S,S+1~T,T+1~R,R+1~N

最外面的两端不经过,所以花费为a[i]

S+1~T这一段只能通过奇数次,剩余两段只能通过偶数次

所以这三段的答案均与奇偶性有关系

因此我们可以得到dp[i][0/1/2/3/4]表示现在考虑到第i个点,这个点属于第1/2/3/4/5段时的最优解

转移非常简单,详见代码

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define int long long
const int inf = 1e16+7;
int dp[200100][5],a[200100];
inline int wh2(int x){
    if(x==0)return 2;
    return x%2;
}
inline int wh1(int x){
    if(x==0)return 1;
    return (x%2)^1;
}
signed main(){
    int n,m,i,j,k;
    scanf("%lld",&n);
    for(i=1;i<=n;i++)scanf("%lld",&a[i]);
    for(i=1;i<=n;i++)
      for(j=0;j<5;j++)
        dp[i][j]=inf;
    for(i=0;i<5;i++)dp[0][i]=0;
    for(i=1;i<=n;i++){
      int wh=dp[i-1][0];
      dp[i][0]=wh+a[i];
      wh=min(wh,dp[i-1][1]);
      dp[i][1]=wh+wh2(a[i]);
      wh=min(wh,dp[i-1][2]);
      dp[i][2]=wh+wh1(a[i]);
      wh=min(wh,dp[i-1][3]);
      dp[i][3]=wh+wh2(a[i]);
      wh=min(wh,dp[i-1][4]);
      dp[i][4]=wh+a[i];
    }
    cout<<min(dp[n][2],min(dp[n][3],dp[n][4]))<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/10360840.html