Laoj P1659 noip模擬 - 道路規劃(LCS的nlogn算法)
阿新 • • 發佈:2017-08-10
ble jpg hspa 都是 target net borde 輸入 c數組
試題描述 |
吉麗王國有n個城市,每個城市有兩個“附屬城市”,其中北部有n個城市,每個城市的編號都是1~n中的一個,且互不相同,南部的n個城市也是如此。 很遺憾,南北兩邊的城市之間還沒有道路連接,這個南北交通運輸帶來了很大的麻煩。 國王吉麗設計規劃了一種方案,決定先建n條道路,即編號相同的兩個城市之間連上一條道路。 如圖所示,這就是建完道路後的樣子。 如果第i個城市和第j個城市的兩條道路相交了,那麽我們稱這兩個城市“平等互惠”。 吉麗想找出一個城市集合,使得集合中的任意兩個城市都“平等互惠”,吉麗還希望這個集合的大小盡可能大。 那最大是多少呢,請你回答他。 |
輸入格式 |
第一行,一個整數,n。 第二行,n個整數,第i個數表示北部第i個城市的編號。 第三行,n個整數,第i個數表示南部第i個城市的編號。 |
輸出格式 |
輸出合法的城市集合的最大大小。 |
輸入示例 |
5 1 4 5 2 3 3 4 2 1 5 |
輸出示例 |
3 |
註釋說明 |
【樣例解釋】 {1,3,4},{1,2,3}和{2,3,5}都是合法的方案,大小是3,顯然是最大值。 【數據規模】 對於20%數據,n<=50; 對於50%數據,n<=500; 對於70%數據,n<=5000; 對於100%數據,n<=10^5。 |
【分析】
一開始的想法是先預處理然後求個lis之類的,也算靠了點邊。
後來發現把第二個序列翻轉後,取二者的lcs即可,數據範圍10^5,明顯留給nlogn的。
LCS的nlogn算法其實就是把LCS轉成LIS,LIS的nlogn算法想必大家都會了。
怎麽轉化呢,舉個栗子:
比如樣例數據是1 4 5 2 3和3 4 2 1 5,第二個序列翻轉後為5 1 2 4 3,用c[i]來表示第一個序列的第i個數在第二個序列中的位置。
此時c[5]={4, 2, 5, 3, 1},現在再對c數組求LIS就可以了。
註意,要求是集合中任意兩個城市都為“平等互惠”,如果我們求出來LCS=1的話,這個集合就為空。
【代碼】
1 #include <bits/stdc++.h> 2 #define inf 0x7fffffff 3 using namespacestd; 4 5 int n, a[100005], b[100005], c[100005], x, g[100005], ans, k, f[100005]; 6 7 void init() { 8 cin >> n; 9 for (int i=1;i<=n;++i) 10 scanf("%d", &a[i]); 11 for (int i=n;i>0;--i) { 12 scanf("%d", &x); 13 b[x]=i; 14 } 15 for (int i=1;i<=n;++i) 16 c[i]=b[a[i]]; 17 } 18 19 void lis() { 20 for (int i=1;i<=n;++i) 21 g[i]=inf; 22 for (int i=1;i<=n;++i) { 23 k=lower_bound(g+1, g+n+1, c[i])-g; 24 g[k]=c[i]; 25 f[i]=k; 26 ans=max(ans, f[i]); 27 } 28 } 29 30 int main() { 31 init(); 32 lis(); 33 if (ans!=1) 34 cout << ans << endl; 35 else 36 cout << 0 << endl; 37 }
Laoj P1659 noip模擬 - 道路規劃(LCS的nlogn算法)