UVA 111 历史考试
题目描述:最长公共子序列的变形
题目序列中第i项是学生给第i号历史事件排出的序号,另外还给出了第i号历史事件的正确序号
求按照学生给出的序号排好历史事件后,所得的事件排序与历史事件实际发生的序列的最长公共子序列
分析:本题最坑的地方是审题,注意题目给出的是给第i号历史事件排出序号,求的却是按照序号排好事件后与历史事件实际发生的序列的最长公共子序列,只要将事件按所给序号排好后就完完全全是一个求最长公共子序列的题了;审题中另一个比较坑的地方是题目详细叙述了“历史考试评分”的两种策略,却明确要求你仅用第二种策略计算
rank[temp]=i ,表示排好序后第temp个发生的事件是编号为i的事件
1 #include<cstdio> 2 #include<cstring> 3 4 int max(int a,int b) 5 { 6 return a>b ? a : b; 7 } 8 int main() 9 { 10 int n,rank1[30],rank2[30]; 11 int d[30][30],i,j; 12 scanf("%d",&n); 13 int temp; 14 for(i=1;i<=n;i++) 15 { 16 scanf("%d",&temp); 17 rank1[temp]=i; 18 } 19 while(scanf("%d",&temp)!=EOF) 20 { 21 rank2[temp]=1; 22 for(i=2;i<=n;i++) 23 { 24 scanf("%d",&temp); 25 rank2[temp]=i; 26 } 27 memset(d,0,sizeof(d)); 28 for(i=1;i<=n;i++) 29 for(j=1;j<=n;j++) 30 { 31 if(rank1[i]==rank2[j]) 32 d[i][j]=d[i-1][j-1]+1; 33 else 34 d[i][j]=max(d[i-1][j],d[i][j-1]); 35 } 36 printf("%d\n",d[n][n]); 37 } 38 }