这道题的解法应该是很多的,但是这道题的时间和空间复杂度的限制,看到的解法大都是DP或搜索加剪枝。我之前Trie的解法空间超过了16M的限制,没法通过,这里也是看到网上的答案写的。DP的想法实际非常简单。这里不再赘述。naive的DP应该是2维的,非常直观,但考虑到f[i][j]只和f[i - 1][j - 1]有关后,我们实际只需要保存一行(一维),不断覆盖就可以。标准答案的方法更聪明,按照斜对角线的方式赋值的,所以不需要额外的存储空间(常数空间)。
/*
ID: thestor1
LANG: C++
TASK: theme
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <climits>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
int main()
{
ifstream fin("theme.in");
ofstream fout("theme.out");
int N;
fin>>N;
std::vector<int> melody(N);
int note;
for (int i = 0; i < N; ++i)
{
fin>>note;
melody[i] = note;
}
// cout<<"melody: ";
// for (int i = 0; i < N; ++i)
// {
// cout<<melody[i]<<"\t";
// }
// cout<<endl;
// std::vector<std::vector<int> > f(N, std::vector<int>(N, 1));
std::vector<int> f(N, 1);
int prev, next;
int maxl = 0;
for (int i = 0; i < N; ++i)
{
for (int j = i + 1; j < N; ++j)
{
if (i == 0 || j == 0)
{
prev = 1;
f[j] = 1;
// // f[i][j] = 1;
continue;
}
if (melody[i] - melody[i - 1] == melody[j] - melody[j - 1])
{
next = f[j];
f[j] = prev + 1;
prev = next;
// f[i][j] = f[i - 1][j - 1] + 1;
// if (f[i][j] >= 5 && f[i][j] > maxl && i < j - (f[i][j] - 1))
// {
// maxl = f[i][j];
// }
if (f[j] >= 5 && f[j] > maxl && i < j - (f[j] - 1))
{
maxl = f[j];
}
}
else
{
// f[i][j] = 1;
prev = f[j];
f[j] = 1;
}
}
}
fout<<maxl<<endl;
fin.close();
fout.close();
return 0;
}