昨晚寫的時候序號2的6分點沒過
今天終於去了趟市裏,從小到大第一次,真不容易。。。回來坐車上看着窗外,想了想這題,瞬間想到了。。。
說說我的思路:(以題目中例子爲例)
因爲第二行給定顏色序列你肯定要分清先後關係,這裏我就用1~m(m是給定的顏色個數)與給定的2、3、1、5、6一一映射 ,
2、3、1、5、6映射 1、2、3、4、5再由1、2、3、4、5映射回2、3、1、5、6;
當然估計有其他好的辦法,我反正怎麼看都覺得繁,沒準可以寫一個找前驅的函數,應該也很簡單,或者比如a[6] = 5, a[5] = 1, a[1] = 3。。。
因爲題目中給了n,數組範圍確定
可設置三個數組:
1、喜歡的顏色序號 找到 喜歡的顏色的順序,a[2] = 1, a[3] = 2, a[1] = 3。。。
2、喜歡的顏色的順序 找到 喜歡的顏色序號,b[1] = 2, b[2] = 3, b[3] = 1。。。
3、暫存喜歡的顏色序號在長度L的色譜?上的符合題目要求的最大字串長:
比如例子:2 2 4 1 5 5 6 3 1 1 5 6
1 2 3 4 5 6 3 4 5 6 7
第1個掃描到2,則count[2] = 1
第2個掃描到2,則count[2] = count[2]
+ 1 = 2
第3個跳過
第4個掃描到1,則count[1] = count[2]
+ 1 = 3
第5個掃描到5,則count[5]
= count[1] + 1 = 4
第6個掃描到5,則count[5]
= count[5] + 1 = 5
。。
。。
昨天是這樣想的,每次都找到第一個等於小於當前顏色順序且count值不爲0的序號,然後操作count[當前序號] = count[找到的序號] + 1;
結果有一個點沒過,其實就是這種情況:
L的序列爲 2 2 5 2 2 5
按照原先的想法就是 1 2 3 3 4 4
其實應該 1 2 3 3 4 5
重點在於每次應該找到序號順序小於等於當前序號的順序,並且count值最大的那個序號,令count[當前序號] = count[找到count值最大的序號] + 1;
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<string>
#include<set>
using namespace std;
int main(){
int n, m, l;
cin>>n>>m;
int a[n + 1] = {0};
int b[n + 1] = {0};
int count[n + 1] = {0};//統計個數
for(int i = 1; i <= m; i++){
int temp;
scanf("%d",&temp);
a[temp] = i;//前後順序用1~n
b[i] = temp;
}
cin>>l;
int sum[l] = {0};
int maxl = 0;
for(int i = 0; i < l; i++){
int temp;
scanf("%d",&temp);
if(a[temp] == 0) continue;
int k = a[temp];
int maxk = 0;
int tempmax = 0;
while(k > 0){
if(tempmax < count[b[k]]){
tempmax = count[b[k]];
maxk = k;
}
k--;
}
if(maxk == 0) maxk++;
count[b[a[temp]]] = count[b[maxk]] + 1;//count[temp] = count[b[maxk]] + 1;等價
sum[i] = count[b[a[temp]]];//sum[]可不寫,寫的話直觀一點
if(maxl < sum[i]) maxl = sum[i];
}
cout<<maxl;
return 0;
}