总结:能这么DP就这么写!
多练位运算标记。
#include<bits/stdc++.h> using namespace::std; const int N=55; const int INF=0x3f3f3f3f; int n, m, dp[N][2][2][2]; char s[N][N]; bool isdigit(char ch) { if(ch>='0' && ch<='9') return true; return false; } bool isletter(char ch) { if(ch>='a' && ch<='z') return true; return false; } bool issymbols(char ch) { if(ch=='*' || ch == '&' || ch == '#') return true; return false; } int solve(int pos, bool digit, bool letter, bool symbols) { if(pos==n) { if(digit && letter && symbols) return 0; return INF; } if(dp[pos][digit][letter][symbols] != -1) return dp[pos][digit][letter][symbols]; int ans=INF; for(int j=0; j<m; j++) { int cost = min(j, m-j); if(isdigit(s[pos][j])) ans = min(ans, cost+ solve(pos+1, 1, letter, symbols)); else if(isletter(s[pos][j])) ans = min(ans, cost+ solve(pos+1, digit, 1, symbols)); else if(issymbols(s[pos][j])) ans = min(ans, cost+ solve(pos+1, digit, letter, 1)); } return dp[pos][digit][letter][symbols]=ans; } int main() { scanf("%d%d",&n,&m); for(int i=0; i<n; i++) scanf("%s",s[i]); memset(dp, -1, sizeof(dp)); printf("%d\n",solve(0,0,0,0)); return 0; }