AT_yahoo_procon2019_qual_d题解

AT_yahoo_procon2019_qual_d

题目传送门

题解

注意到走一个来回不影响其他点,所以我们本质上只有 \(3\) 种数:奇数(\(1\))、偶数(\(2\))和 \(0\)

去除所有来回,我们发现所有合法路径都可以被抽象成这样:

000222221111122222000
---A---S-----T---B---
   <---<
   >------------->
             <---<

我们设 \(f_{i,j}\) 表示当前到 \(i\),位于第 \(j\) 段的最小代价,转移显然,详见代码。

虽然其中的 \(A,S,T,B\) 可能重合,故不是一定有 \(5\) 段,不过这无所谓,因为我们是 dp。

\(O(1)\) 空间的代码:

/*
 * @Author: operator_ 
 * @Date: 2024-01-09 14:31:46 
 * @Last Modified by: operator_
 * @Last Modified time: 2024-01-09 14:55:27
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int rd() {
    int s=0,m=0;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-')m=1;ch=getchar();}
    while( isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
    return m?-s:s;
}
int n,a,f[6];
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++) {
        f[2]=min(f[1],f[2]),f[3]=min(f[2],f[3]),f[4]=min(f[3],f[4]),f[5]=min(f[4],f[5]);
        a=rd(),f[1]+=a,f[2]+=!a?2:a%2,f[3]+=1-a%2,f[4]+=!a?2:a%2,f[5]+=a;
    }
    cout<<min(f[1],min(f[2],min(f[3],min(f[4],f[5]))));
    return 0;
}
posted @ 2024-01-19 15:23  operator-  阅读(33)  评论(0)    收藏  举报