zoukankan      html  css  js  c++  java
  • uva111动态规划之最长公共子序列

     
     
        
    C - Largest Rectangle in a Histogram
    Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

    Description

    Download as PDF

    Background

    Many problems in Computer Science involve maximizing some measure according to constraints.

    Consider a history exam in which students are asked to put several historical events into chronological order. Students who order all the events correctly will receive full credit, but how should partial credit be awarded to students who incorrectly rank one or more of the historical events?

    Some possibilities for partial credit include:

    1. 1 point for each event whose rank matches its correct rank
    2. 1 point for each event in the longest (not necessarily contiguous) sequence of events which are in the correct order relative to each other.

    For example, if four events are correctly ordered 1 2 3 4 then the order 1 3 2 4 would receive a score of 2 using the first method (events 1 and 4 are correctly ranked) and a score of 3 using the second method (event sequences 1 2 4 and 1 3 4 are both in the correct order relative to each other).

    In this problem you are asked to write a program to score such questions using the second method.

    The Problem

    Given the correct chronological order of n events tex2html_wrap_inline34 as tex2html_wrap_inline36 where tex2html_wrap_inline38 denotes the ranking of event i in the correct chronological order and a sequence of student responses tex2html_wrap_inline42 where tex2html_wrap_inline44 denotes the chronological rank given by the student to event i; determine the length of the longest (not necessarily contiguous) sequence of events in the student responses that are in the correct chronological order relative to each other.

    The Input

    The first line of the input will consist of one integer n indicating the number of events with tex2html_wrap_inline50 . The second line will contain nintegers, indicating the correct chronological order of n events. The remaining lines will each consist of n integers with each line representing a student's chronological ordering of the n events. All lines will contain n numbers in the range tex2html_wrap_inline60 , with each number appearing exactly once per line, and with each number separated from other numbers on the same line by one or more spaces.

    The Output

    For each student ranking of events your program should print the score for that ranking. There should be one line of output for each student ranking.

    Sample Input 1

    4
    4 2 3 1
    1 3 2 4
    3 2 1 4
    2 3 4 1

    Sample Output 1

    1
    2
    3

    Sample Input 2

    10
    3 1 2 4 9 5 10 6 8 7
    1 2 3 4 5 6 7 8 9 10
    4 7 2 3 10 6 9 1 5 8
    3 1 2 4 9 5 10 6 8 7
    2 10 1 3 8 4 9 5 7 6
    

    Sample Output 2

    6
    5
    10
    9
    

     最长公共子序列(Longest Common Subsequence)
    问题大意 给定两个序列 A 和 B,求 A 和 B 的最长公共子序列。子序列即从最初序 列去除某些元素但不破坏余下元素的相对位置而得到的新序列 1。
    对应题目 HOJ 1227 1316
    分析 子序列是从原序列中去掉某些元素所得到的序列,注意到原序列前缀的子序列 也是原序列的子序列,而且如果要得到的公共子序列最长,那么把公共子序列的最后 一个元素去掉之后,所得的序列应该是 A 和 B 某个前缀的 LCS。例如 A = abcdabcd, B = acdbcdb,目测知 A 和 B 的最长公共子序列应该是 S = acdcd,假如把最后一个匹 配的 d 去掉,得到的 acdc 显然是 C = abcdabc 和 D = acdbc 的 LCS,否则如果 C、 D 存在更长的 LCS,那么这个 LCS 加上 d,得到了比 S 更长的串,且该串是 A 和 B 的 LCS。 有了这个结论,余下的问题就比较明显了,用 dp[i,j] 表示 A 的前 i 个字符与 B 的 前 j 个字符的 LCS,则有 dp[i,j] ={max(dp[i−1,j −1] + 1,dp[i−1,j],dp[i,j −1]), if A[i] = B[i] max(dp[i−1,j],dp[i,j −1]), if A[i] ̸= B[j] 边界和初值比较容易,这里不再说明。思考最后的答案的取值应该在哪里,对比一下方 格取数与 LCS 的不同。 时间和空间复杂度都是 O(n2)。

     1 /*
     2  【题目大意】
     3 一个历史考试,有n个历史事件, 它们之间的年份是不同的,要学生把这些事件按照正确
     4 的顺序排列出来。有两种记分方式,
     5 采用的是第二种: 假设有历史事件1,2,3,4,
     6 它们正确的时间顺序是1,2,3,4, 然后假设学生的答案是1,3,2,4, 那么按照相
     7 对顺序正确的数量,答对了三个
     8 (1,2,4或者1,3,4),也就是它与正确答案的最长
     9 公共子序列长度是3,便是答对的数量。
    10 
    11 【分析与总结】
    12 最长公共子序列模板题,但是这题的输入是个很大的坑,他的输入是按照顺序,事件1是排在第几位,
    13 事件2是排在第几位......, 所以要先把输入转换成正确的顺序。
    14 
    15 【代码】
    16  */
    17 #include<iostream>
    18 #include<cstring>
    19 #include<cstdio>
    20 using namespace std;
    21 int order[25], arr[25], d[25][25];
    22 
    23 int main()
    24 {
    25     int n, t;
    26     scanf("%d",&n);
    27     // 读入正确的答案顺序
    28     for(int i=0; i<n; i++)
    29     {
    30         scanf("%d",&t);
    31         order[t-1]=i+1; //放入他排名的位置,所以order就是正确的答案
    32     }
    33     while(scanf("%d",&t)!=EOF)
    34     {
    35         arr[t-1]=1;
    36         for(int i=1; i<n; ++i)
    37         {
    38             scanf("%d",&t);
    39             arr[t-1]=i+1;
    40         }
    41         // 求出最长公共子序列长度
    42         memset(d, 0, sizeof(d));
    43         for(int i=0; i<n; ++i)
    44         {
    45             for(int j=0; j<n; ++j)
    46             {
    47                 if(order[i]==arr[j])
    48                     d[i+1][j+1]=max(max(d[i][j]+1,d[i][j+1]),d[i+1][j]);
    49                 else
    50                     d[i+1][j+1]=max(d[i][j+1],d[i+1][j]);
    51             }
    52         }
    53         printf("%d
    ", d[n][n]);
    54     }
    55     return 0;
    56 }
     
  • 相关阅读:
    python检索特定内容的文本文件2
    windows dll函数的导出
    python检索特定内容的文本文件
    python 建立ftp共享文件夹
    gitbook制作电子书
    MFC程序框架
    Python 中文文档下载(附下载链接)
    基于tensorflow的手写数字识别代码
    MySQL
    vue项目更新数组对象里面的属性值,实现UI界面重新渲染---$set
  • 原文地址:https://www.cnblogs.com/SSYYGAM/p/4529414.html
Copyright © 2011-2022 走看看