题意:题意就是坑,看不大懂么,结果就做不对,如果看懂了就so easy了,给定n个事件,注意的是,
它给的是第i个事件发生在第多少位,并不是像我们想的,第i位是哪个事件,举个例子吧,4 2 3 1,
表示的是第一个事件发生在第四,第二个事件发生在第二位,第三个在第三位,第四个在第一位。
然后输入n个答案,求有多少个事件相对位置是和原来一样的。
那么知道输入好办了,我们只需对输入做一下预处理,就变成了LIS。
代码如下:
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <cstring> #include <map> using namespace std; const int maxn = 20 + 5; int d[maxn], a[maxn], id[maxn]; int main(){ int n, x; cin >> n; for(int i = 1; i <= n; ++i){ scanf("%d", &x); id[i] = x;//第i个事件发生在第x位 } while(~scanf("%d", &x)){ a[0] = -10; a[x] = id[1]; for(int i = 2; i <= n; ++i){ scanf("%d", &x); a[x] = id[i];//查找第x个事件编号是几 } memset(d, 0, sizeof(d)); int m = 0; for(int i = 1; i <= n; ++i){//LIS for(int j = 0; j < i; ++j) if(a[i] > a[j] && d[j]+1 > d[i]) d[i] = d[j] + 1; m = max(m, d[i]); } printf("%d\n", m); } return 0; }
网上大数都是用LCS做,其实都差不多。
用LCS代码如下:
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <cstring> #include <map> using namespace std; const int maxn = 20 + 5; int d[maxn][maxn], a[maxn], id[maxn]; int main(){ int n, x; cin >> n; for(int i = 1; i <= n; ++i){ scanf("%d", &x); id[x] = i; } while(~scanf("%d", &x)){ a[0] = -10; a[x] = 1; // a[x] = id[1]; for(int i = 2; i <= n; ++i){ scanf("%d", &x); a[x] = i; // a[x] = id[i]; } memset(d, 0, sizeof(d)); int m = 0; for(int i = 1; i <= n; ++i){ for(int j = 1; j <= n; ++j) if(id[i] == a[j]) d[i][j] = d[i-1][j-1] + 1; else d[i][j] = max(d[i-1][j], d[i][j-1]); // m = max(m, d[i]); } printf("%d\n", d[n][n]); } return 0; }