uva 10635 Prince and Princess

來源:互聯網
上載者:User

原題:
In an n×n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered
1,2,3,…,n ∗ n, as shown below:

Prince stands in square 1, make p jumps and finally reach square n∗n. He enters a square at most
once. So if we use xpto denote the p-th square he enters, then x1, x2, …, xp+1are all different. Note
that x1= 1 and xp+1= n ∗ n. Princess does the similar thing – stands in square 1, make q jumps and
finally reach square n ∗ n. We use y1, y2, …, yq+1to denote the sequence, and all q + 1 numbers are
different.
Figure 2 belows show a 3×3 square, a possible route for Prince and a different route for Princess.

The Prince moves along the sequence: 1 –> 7 –> 5 –> 4 –> 8 –> 3 –> 9 (Black arrows), while the
Princess moves along this sequence: 1 –> 4 –> 3 –> 5 > 6 –> 2 –> 8 –> 9 (White arrow).
The King – their father, has just come. “Why move separately? You are brother and sister!” said
the King, “Ignore some jumps and make sure that you’re always together.”
For example, if the Prince ignores his 2nd, 3rd, 6th jump, he’ll follow the route: 1 –> 4 –> 8 –>
9. If the Princess ignores her 3rd, 4th, 5th, 6th jump, she’ll follow the same route: 1 –> 4 –> 8 –>
9, (The common route is shown in figure 3) thus satisfies the King, shown above. The King wants to
know the longest route they can move together, could you tell him?
Input
The first line of the input contains a single integer t (1 ≤ t ≤ 10), the number of test cases followed.
For each case, the first line contains three integers n, p, q (2 ≤ n ≤ 250, 1 ≤ p,q < n ∗ n). The second
line contains p+1 different integers in the range [1…n∗n], the sequence of the Prince. The third line
contains q + 1 different integers in the range [1…n ∗ n], the sequence of the Princess.
Output
For each test case, print the case number and the length of longest route. Look at the output for sample
input for details.
Sample Input
1
3 6 7
1 7 5 4 8 3 9
1 4 3 5 6 2 8 9
Sample Output
Case 1: 4
大意:
給你兩個數字序列,每個數字序列當中不存在重複的數字。問你這兩個數字序列的最長公用子序列是多少。

#include <bits/stdc++.h>using namespace std;int dp[62501];int ce[62501],ess[62501],mark[62501];int main(){    ios::sync_with_stdio(false);    int t,k=1,n,p,q,ans;    cin>>t;    while(t--)    {        cin>>n>>p>>q;        ans=0;        memset(mark,0,sizeof(mark));        for(int i=1;i<=p+1;i++)        {            cin>>ce[i];            mark[ce[i]]=i;        }        for(int i=1;i<=q+1;i++)        {            cin>>n;            ess[i]=mark[n];            dp[i]=INT_MAX;        }        for(int i=1;i<=q+1;i++)        {            int index=lower_bound(dp+1,dp+1+i,ess[i])-dp;            dp[index]=ess[i];            ans=max(ans,index);        }        cout<<"Case "<<k++<<": "<<ans<<endl;    }    return 0;}

解答:
上來就用lcs,明知道時間複雜度肯定會掛,但我還是試了一試,果然逾時=_=
在那個lucky貓上面的標籤上面看到這道題的標籤lis,也就是最長遞增子序列。當時很納悶,這題怎麼用最長遞增子序列解啊。簡單想了一會,百度最長公用子序列 o(nlogn)結果居然真的有,而且翻了翻lrj的訓練指南,發現書上也有這道題的例題。仔細端詳過後感覺想出這方法的人真是好聰明啊。
最長公用子序列o(nlogn)演算法
操作步驟,先設兩個序列分別為a和b,數字個數分別為la,lb。然後把a中的數字重新按照1到la排序。
比如範例當中a={1,7,5,4,8,3,9}重新編排後變成{1,2,3,4,5,6,7}。然後對應到b當中,如果沒有的就用0代替
b變成{1,4,6,3,0,0,5,7},然後求b的最長遞增子序列就行了,別腦袋發熱又寫了個o(n^2)的演算法要用二分的那個。
想了一會為啥這樣做就能算是找到最長公用子序列了呢。我的理解,應該是把a中的序列重新編排後再映射到b中,這個映射的過程就相當於在是b中標記處了a當中的元素,重排之後的a是遞增的,所以找b當中的最長遞增序列就相當於找到了本序列和a序列當中最多重合的元素。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.