P9408 『STA - R2』Locked 题解
题目大意
有一串由数字
题目分析
乍一看可能感觉这题是贪心,但仔细一想会发现操作之间是相牵连的,故放弃贪心,更换思考角度。
可以发现,单调不减和单调不增是好解决的,可以设计状态
update:这里要注意,计算答案时由于 dp_{i,j} 和 f_{i,j} 都计算了一次 dis_{a_i,j} ,所以还得减去一次 dis_{a_i,j} 。
#include<bits/stdc++.h>
#define ll long long
#define L x<<1
#define R x<<1|1
#define mid (l+r>>1)
#define lc L,l,mid
#define rc R,mid+1,r
#define rep(x,y,z) for(int x=(y);x<=(z);x++)
using namespace std;
const int N=5e6+5;
inline int read(){int s=0,w=1;char c=getchar();while(c<48||c>57) {if(c=='-') w=-1;c=getchar();}while(c>=48&&c<=57) s=(s<<1)+(s<<3)+c-48,c=getchar();return s*w;}
inline void pf(ll x){if(x<0) putchar('-'),x=-x;if(x>9)pf(x/10);putchar(x%10+48);}
int n,a[N],f[N][10],g[N][10],ff[10],ans=2147000000;
inline int dis(int x,int y){
return min(abs(x-y),10-abs(x-y));
}
int main(){
n=read();
rep(i,1,n)a[i]=read();
rep(i,0,9)f[1][i]=dis(a[1],i),g[n][i]=dis(a[n],i);
ff[0]=f[1][0];
rep(i,1,9)ff[i]=min(ff[i-1],f[1][i]);
rep(i,2,n){
f[i][0]=ff[0]+dis(a[i],0);
ff[0]=f[i][0];
rep(j,1,9)f[i][j]=ff[j]+dis(a[i],j),ff[j]=min(ff[j-1],f[i][j]);
}
ff[0]=g[n][0];
rep(i,1,9)ff[i]=min(ff[i-1],g[n][i]);
for(int i=n-1;i>=1;i--){
g[i][0]=ff[0]+dis(a[i],0);
ff[0]=g[i][0];
rep(j,1,9)g[i][j]=ff[j]+dis(a[i],j),ff[j]=min(ff[j-1],g[i][j]);
}
rep(i,1,n)rep(j,0,9){
ans=min(ans,f[i][j]+g[i][j]-dis(a[i],j));
}
cout <<ans;
return 0;
}