USACO 5.4.2 以后在理解
这道题的意思是到现在理解的不太透彻, 以后需要在看, 先把代码贴上吧
/* ID: m1500293 LANG: C++ PROG: charrec */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const char letter[30] = " abcdefghijklmnopqrstuvwxyz"; int ans[1201]; int font[28][21][21]; int data[1201][21], dif[28][21][1201]; //dif表示第i个字符的第j行和输入的第k行的差距 int cost[1201][4]; //表示从第i行开始 int from[1201][4]; int f[1201], g[1201]; int main() { freopen("font.in", "r", stdin); int n; scanf("%d", &n); getchar(); for(int i=1; i<=27; i++) for(int j=1; j<=20; j++) { for(int k=1; k<=20; k++) font[i][j][k] = getchar(); getchar(); } freopen("charrec.in", "r", stdin); freopen("charrec.out", "w", stdout); scanf("%d", &n); getchar(); for(int i=1; i<=n; i++) { for(int j=1; j<=20; j++) data[i][j] = getchar(); getchar(); } //预处理dif数组 for(int i=1; i<=27; i++) for(int j=1; j<=20; j++) for(int k=1; k<=n; k++) for(int p=1; p<=20; p++) if(data[k][p] != font[i][j][p]) dif[i][j][k]++; //预处理cost数组 for(int i=1; i<=n; i++) { cost[i][1] = cost[i][2] = cost[i][3]=0x3fffffff; if(i+18 <= n) //缺失一行 for(int j=1; j<=27; j++) { int total=0; for(int k=2; k<=20; k++) total += dif[j][k][i+k-2]; if(total < cost[i][1]) cost[i][1]=total, from[i][1]=j; for(int k=2; k<=20; k++) { total += dif[j][k-1][i+k-2]; total -= dif[j][k][i+k-2]; if(total<cost[i][1]) cost[i][1]=total, from[i][1]=j; } } if(i+19 <= n) //正好20行 for(int j=1; j<=27; j++) { int total = 0; for(int k=1; k<=20; k++) total += dif[j][k][i+k-1]; if(total < cost[i][2]) cost[i][2]=total, from[i][2]=j; } if(i+20<=n) //多一行 for(int j=1; j<=27; j++) { int total = dif[j][1][i]; for(int k=2; k<=20; k++) total += dif[j][k][i+k]; if(total<cost[i][3]) cost[i][3]=total, from[i][3]=j; for(int k=2; k<=20; k++) //多第k行 { total += dif[j][k][i+k-1]; total -= dif[j][k][i+k]; if(total < cost[i][3]) cost[i][3] = total, from[i][3] = j; } } } int inf = 0x3fffffff; f[0] = 0; for(int i=1; i<=n; i++) f[i] = inf; for(int i=19; i<=n; i++) { if(i>=19 && f[i-19]<inf && f[i-19]+cost[i-18][1]<f[i]) f[i]=f[i-19]+cost[i-18][1], g[i]=19; if(i>=20 && f[i-20]<inf && f[i-20]+cost[i-19][2]<f[i]) f[i]=f[i-20]+cost[i-19][2], g[i]=20; if(i>=21 && f[i-21]<inf && f[i-21]+cost[i-20][3]<f[i]) f[i]=f[i-21]+cost[i-20][3], g[i]=21; } int total = 0; for(int i=n; i; i-=g[i]) ans[++total] = from[i-g[i]+1][g[i]-18]; for(int i=total; i; i--) printf("%c", letter[ans[i]-1]); printf("\n"); return 0; }