ACM-ICPC 2018 徐州赛区网络预赛 F. Features Track
题目
有 n 天,每天有一定量的点对,求点对连续出现最长的天数。
分析
两种方法,
用 存点对,直接枚举每一天的每一个点对能往后连续多少天,连续的后面要标记一下,下次枚举后面的天,不枚举标记过的点对。
或者将点对用 映射成数字,然后动态规划。
表示前 i 天,j 出现的最大连续次数。
,取一个最大值。
模拟
模拟时找后面的天出现过没某一个点对,用 STL中的 方法;
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define pii pair<int, int>
#define mk(x, y) make_pair(x, y)
const int N = 1e5 + 5;
const int M = 1e6 + 5;
int _, n;
vector<pii> v[N];
map<pii, int> m;
int main(){
for (scanf("%d", &_); _; _--){
scanf("%d", &n);
m.clear();
for (int i = 1, k, x, y; i <= n; i++){
scanf("%d", &k);
while(k--){
scanf("%d%d", &x, &y);
v[i].push_back(mk(x, y));
}
}
int ans = 0;
for(int i = 1; i <= n; i++){
int len = v[i].size();
for(int j = 0; j < len; j++){
pii temp = mk(i, j);
if(!m[temp]){
int l = 1;
for (int k = i + 1;; k++, l++){
auto it = find(v[k].begin(), v[k].end(), v[i][j]);
if(it != v[k].end()){
m[mk(k, it - v[k].begin())]++;
}else{
ans = max(ans, l);
break;
}
}
}
}
v[i].clear();
}
printf("%d\n", ans);
}
return 0;
}
DP
用滚动数组优化一下。
就是用两维一直滚动
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define pii pair<int, int>
#define mk(x, y) make_pair(x, y)
const int N = 1e5 + 5;
const int M = 1e6 + 5;
int _, n;
map<pii, int> m[2];
int main(){
for (scanf("%d", &_); _; _--){
scanf("%d", &n);
int cur = 0, ans = 0;
for (int i = 1, k, a, b; i <= n; i++){
cur ^= 1;
m[cur].clear();
scanf("%d", &k);
while(k--){
scanf("%d%d", &a, &b);
pii tmp = mk(a, b);
m[cur][tmp] = m[cur ^ 1][tmp] + 1;
ans = max(ans, m[cur][tmp]);
}
}
printf("%d\n", ans);
}
return 0;
}
/*
33
5
1 1 1
1 2 2
1 2 2
1 1 1
1 2 1
*/
来源:https://blog.csdn.net/GodJing007/article/details/99656320