首页 > 代码库 > USACO5.4-Character Recognition
USACO5.4-Character Recognition
题目大意是字符串识别
一道细节很繁琐的DP,要用到很多数组
一开始还真看不出是DP,后来参考了别人的代码,然后又按自己的思路重头到尾写了,虽然速度不咋的
Executing...
Test 1: TEST OK [0.008 secs, 6504 KB]
Test 2: TEST OK [0.008 secs, 6504 KB]
Test 3: TEST OK [0.019 secs, 6504 KB]
Test 4: TEST OK [0.035 secs, 6504 KB]
Test 5: TEST OK [0.084 secs, 6504 KB]
Test 6: TEST OK [0.116 secs, 6504 KB]
Test 7: TEST OK [0.167 secs, 6504 KB]
Test 8: TEST OK [0.192 secs, 6504 KB]
Test 9: TEST OK [0.178 secs, 6504 KB]
All tests OK.
YOUR PROGRAM (‘charrec‘) WORKED FIRST TIME! That‘s fantastic
-- and a rare thing. Please accept these special automated
congratulations.
1 #include <stack> 2 #include <iostream> 3 #include <stdio.h> 4 #define R19 0 5 #define R20 1 6 #define R21 2 7 #define INF 1000000000 8 using namespace std; 9 10 char ch[28][22][22]; 11 char mat[1210][22]; 12 int dif[28][22][1210]; 13 int cost[1210][4]; // cost[i][j]表示从mat的第i行开始匹配j行得到的最小差距 14 int optimalCh[1210][4]; // optimalCh[i][j]表示从mat的第i行开始匹配j行最优的匹配字符 15 int d[1210]={0}; // d[i]表示匹配到第i行所得到的最小差距 16 int step[1210]; // step[i]表示第i行开始的最优匹配的字符行数 17 // 得到行数中不同的个数 18 /* 19 num为第几个字符 20 l1为num字符的行数 21 l2为mat的行数 22 */ 23 int getDif(int num,int l1,int l2) 24 { 25 int sum=0; 26 for(int i=0;i<20;i++) 27 { 28 if(ch[num][l1][i]!=mat[l2][i]) 29 sum++; 30 } 31 return sum; 32 } 33 34 // num为字符,l1为mat开始匹配的行数,del为删除了哪一行 35 int getCost(int num,int l1,int del) 36 { 37 int sum=0; 38 for(int i=0,p=0;p<19;i++,p++) 39 { 40 if(i==del) 41 i++; 42 sum+=dif[num][i][l1+p]; 43 } 44 return sum; 45 } 46 47 int getCost2(int num,int l1,int del) 48 { 49 int sum=0; 50 for(int i=0,p=0;i<20;i++,p++) 51 { 52 if(p==del) 53 p++; 54 sum+=dif[num][i][p+l1]; 55 } 56 return sum; 57 } 58 59 60 int main() 61 { 62 freopen("font.in","r",stdin); 63 int n; // 行数 64 cin>>n; 65 for(int i=0;i<n/20;i++) 66 { 67 for(int j=0;j<20;j++) 68 { 69 scanf("%s",ch[i][j]); 70 71 } 72 } 73 74 freopen("charrec.in","r",stdin); 75 freopen("charrec.out","w",stdout); 76 77 cin>>n; 78 79 for(int i=0;i<n;i++) 80 scanf("%s",mat[i]); 81 82 // 初始化dif数组 83 for(int i=0;i<27;i++) 84 for(int j=0;j<20;j++) 85 { 86 for(int k=0;k<n;k++) 87 { 88 dif[i][j][k]=getDif(i,j,k); 89 } 90 } 91 92 // 初始化cost 93 for(int i=0;i<n;i++) // 从第i行开始匹配 94 { 95 cost[i][R19]=cost[i][R20]=cost[i][R21]=INF; 96 for(int j=0;j<27;j++) // 第j个字符 97 { 98 if(i+19<n+1) 99 {100 for(int k=0;k<20;k++) // 删掉行数101 {102 if(cost[i][R19]>getCost(j,i,k))103 {104 cost[i][R19]=getCost(j,i,k);105 optimalCh[i][R19]=j;106 }107 }108 }109 if(i+20<n+1)110 {111 if(cost[i][R20]>getCost(j,i,-1))112 {113 cost[i][R20]=getCost(j,i,-1);114 optimalCh[i][R20]=j;115 }116 }117 if(i+21<n+1)118 {119 for(int k=0;k<21;k++) // 多出的行数120 {121 if(cost[i][R21]>getCost2(j,i,k))122 {123 cost[i][R21]=getCost2(j,i,k);124 optimalCh[i][R21]=j;125 }126 }127 }128 }129 }130 131 fill_n(d,n+5,INF);132 // 初始值133 d[18]=cost[0][R19];step[18]=19;134 d[19]=cost[0][R20];step[19]=20;135 d[20]=cost[0][R21];step[20]=21;136 // DP137 for(int i=21;i<n;i++) // 匹配的最后一行为i138 {139 if(d[i-19]+cost[i-18][R19]<d[i])140 {141 d[i]=d[i-19]+cost[i-18][R19];142 step[i]=19;143 }144 if(d[i-20]+cost[i-19][R20]<d[i])145 {146 d[i]=d[i-20]+cost[i-19][R20];147 step[i]=20;148 }149 if(d[i-21]+cost[i-20][R21]<d[i])150 {151 d[i]=d[i-21]+cost[i-20][R21];152 step[i]=21;153 }154 }155 156 stack<int> S;157 158 for(int p=n-1;p!=-1;p=p-step[p])159 {160 S.push(optimalCh[p-step[p]+1][step[p]-19]);161 }162 163 while(!S.empty())164 {165 int tmp=S.top();166 S.pop();167 printf("%c",tmp==0?‘ ‘:tmp-1+‘a‘);168 }169 cout<<endl;170 return 0;171 }
USACO5.4-Character Recognition
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。