codeforces 761C - Dasha and Password (dp)
题目链接:https://codeforces.com/problemset/problem/761/C
设\(dp[i][0/1][0/1][0/1]\)表示前 i 个字符有无数字,字母,特殊符号的最小操作次数
向左向右移动光标找到最小的方向即可
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 100;
int n,m;
int dp[maxn][2][2][2]; // 到第 i 行,前面有无数字,字母,特殊符号的最小操作步数
char s[maxn][maxn];
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
memset(dp,0x3f,sizeof(dp));
n = read(), m = read();
for(int i=1;i<=n;++i){ scanf("%s",s[i]); }
dp[0][0][0][0] = 0;
for(int i=1;i<=n;++i){
dp[i][1][0][0] = dp[i-1][1][0][0];
dp[i][0][1][0] = dp[i-1][0][1][0];
dp[i][0][0][1] = dp[i-1][0][0][1];
dp[i][1][1][0] = dp[i-1][1][1][0];
dp[i][1][0][1] = dp[i-1][1][0][1];
dp[i][0][1][1] = dp[i-1][0][1][1];
dp[i][1][1][1] = dp[i-1][1][1][1];
for(int j=0;j<m;++j){
if(s[i][j] >= '0' && s[i][j] <= '9'){
dp[i][1][0][0] = min(dp[i][1][0][0],dp[i-1][0][0][0]+min(j,m-j));
dp[i][1][1][0] = min(dp[i][1][1][0],dp[i-1][0][1][0]+min(j,m-j));
dp[i][1][0][1] = min(dp[i][1][0][1],dp[i-1][0][0][1]+min(j,m-j));
dp[i][1][1][1] = min(dp[i][1][1][1],dp[i-1][0][1][1]+min(j,m-j));
}else if(s[i][j] >= 'a' && s[i][j] <= 'z'){
dp[i][0][1][0] = min(dp[i][0][1][0],dp[i-1][0][0][0]+min(j,m-j));
dp[i][1][1][0] = min(dp[i][1][1][0],dp[i-1][1][0][0]+min(j,m-j));
dp[i][0][1][1] = min(dp[i][0][1][1],dp[i-1][0][0][1]+min(j,m-j));
dp[i][1][1][1] = min(dp[i][1][1][1],dp[i-1][1][0][1]+min(j,m-j));
}else{
dp[i][0][0][1] = min(dp[i][0][0][1],dp[i-1][0][0][0]+min(j,m-j));
dp[i][1][0][1] = min(dp[i][1][0][1],dp[i-1][1][0][0]+min(j,m-j));
dp[i][0][1][1] = min(dp[i][0][1][1],dp[i-1][0][1][0]+min(j,m-j));
dp[i][1][1][1] = min(dp[i][1][1][1],dp[i-1][1][1][0]+min(j,m-j));
}
}
}
printf("%d\n",dp[n][1][1][1]);
return 0;
}