• UVa 111 History Grading (简单DP,LIS或LCS)


    题意:题意就是坑,看不大懂么,结果就做不对,如果看懂了就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
    ", 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
    ", d[n][n]);
        }
    
        return 0;
    }
    
  • 相关阅读:
    C#延时
    Java Applet 绘图
    C#调用ActiveX控件异常处理
    J2SE连连看
    基于对象的棋类程序结构设计
    MATLAB应用专题part2电力电子仿真技术
    MATLAB应用专题part1电力电子仿真技术
    硬件知识整理part2电阻在反馈网络中的应用
    C语言再学习part1宏观认识C语言
    C语言再学习part3—算法
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5549765.html
Copyright © 2020-2023  润新知