题目大意是给n个帧,每个帧有m个特征,特征用一个二元组表示,求在连续的帧中出现的特征的连续出现次数。
-
第一反应想了一个很麻烦的做法,没想到别人的代码直接用map冲过去的。
-
二元组用个pair或者hash一下然后用map离散化,然后反过来转化为每个特征对应出现的帧的下标值,得到这样一个邻接表,然后对于每个特征,就是要求出对应vector数组里最长连续加1上升子序列长度,简单的dp一下。
-
多组样例最好用queue记录一下用过的dp值再清空,不过似乎数据特别水...
-
别人的做法大多是直接维护两个map,记录特征连续出现的次数,然后扫一遍即可。
-
code1
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+50;
int T,n,m,x,y;
map<pair<int,int>,int> mp;
vector<int> g[N];
int dp[N];
queue<int> q;
int main(){
scanf("%d",&T);
while(T--){
int cnt=1;
mp.clear();
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&m);
for(int j=1;j<=m;j++){
scanf("%d%d",&x,&y);
if(mp.find({x,y})==mp.end()){
mp[{x,y}]=cnt++;
}
g[mp[{x,y}]].push_back(i);
}
}
int ans=0;
for(int i=1;i<cnt;i++){
int siz=g[i].size();
for(int j=0;j<siz;j++){
//连续+1上升子序列
q.push(g[i][j]);
dp[g[i][j]]=dp[g[i][j]-1]+1;
ans=max(ans,dp[g[i][j]]);
}
while(!q.empty()){
dp[q.front()]=0;
q.pop();
}
g[i].clear();
}
printf("%d
",ans);
}
return 0;
}
- code2
#include <bits/stdc++.h>
using namespace std;
int T,n,m,x,y;
map<pair<int,int>,int> pre,now;
int main(){
scanf("%d",&T);
while(T--){
pre.clear();
now.clear();
scanf("%d",&n);
int ans=0;
for(int i=1;i<=n;i++){
scanf("%d",&m);
for(int j=1;j<=m;j++){
scanf("%d%d",&x,&y);
if(pre.find({x,y})==pre.end()){
now[{x,y}]=1;
}else{
now[{x,y}]=pre[{x,y}]+1;
}
ans=max(ans,now[{x,y}]);
}
pre=now;
now.clear();
}
printf("%d
",ans);
}
return 0;
}