uva 111 History Grading

来源:互联网 发布:linux du显示行号 编辑:程序博客网 时间:2024/06/09 13:48

题目大意:给出一个由历史事件的发生的先后顺序组成的标准答案,以及若干的试卷答案,要你比对正确的个数,也就是两个序列的最大公共子序列长度。

题目思路:经典模型,状态转移方程:A[i]==B[i]时,dp(x,y) = dp(x-1,y-1)+1,否则dp(x,y) = max(dp(x-1,y),dp(x,y-1))

题目坑点:并不是要你求给你的两个序列的最大公共子序列长度。而是要先转化,以

3 1 2 4 9 5 10 6 8 7为例,意思是第一个事件第三个发生,第二个事件第一个发生,那重排以后的序列的第一项就应该是2,即代表第一个发生的事件的编号。
代码如下:可以改进的地方有:将输入与转化的过程另外写一个函数。
#include <iostream>#include <stdio.h>#include <fstream>#include <iomanip>#include <cmath>#include <string>#include <string.h>#include <sstream>#include <cctype>#include <climits>#include <set>#include <map>#include <queue>#include <vector>#include <iterator>#include <algorithm>#include <stack>#include <functional>/*int类型最大值INT_MAX,short最大值为SHORT_MAXlong long最大值为LONG_LONG_MAX*///cout << "OK" << endl;#define _clr(x) memset(x,-1,sizeof(x))using namespace std;const int INF = INT_MAX;const double eps = 1e-8;const double EULER = 0.577215664901532860;const double PI = 3.1415926535897932384626;const double E = 2.71828182845904523536028;typedef long long LL;int n,a[100],b[100],ans[100],ans2[100],res[100][100];int dp(int x,int y){if(x == -1||y == -1) return 0;if(res[x][y] != -1) return res[x][y];if(a[x] == ans[y]) return res[x][y] = dp(x-1,y-1)+1;else return res[x][y] = max(dp(x-1,y),dp(x,y-1));}int main(){    //freopen("sample.in", "r", stdin);//freopen("sample.out", "w", stdout);cin >> n;for(int i = 0;i<n;i++) cin >> b[i];for(int i = 0;i<n;i++) a[b[i]-1] = i+1;//for(int i = 0;i<n;i++)cout << a[i] << " ";//cout << endl;while(cin >> ans2[0]){_clr(res);for(int i = 1;i<n;i++) cin >> ans2[i];for(int i = 0;i<n;i++) ans[ans2[i]-1] = i+1;cout << dp(n-1,n-1) << endl;}    //fclose(stdin);    //fclose(stdout);     return 0;}

0 0
原创粉丝点击