1. 题目来源
链接:数列重组
2. 题目解析
暴力枚举全排列,再暴力判断三段是否有序即可。
- 全排列:有序数组下,采用
next_permutation(q.begin(), q.end())
。 - 判断有序:
is_sorted(a.begin(), a.end(), cmp)
其默认为升序排序,支持自定义排序。
常见简化代码的操作。枚举将数组分成三段,就枚举分界点即可,但是要注意,区间一定是左开右闭的,若是 [1,1)
其实里面是没有数的,is_sorted()
在此时会判断成功,显然是错误的。
- 时间复杂度: O ( n 2 n ! ) O(n^2n!) O(n2n!),不确定…
- 空间复杂度: O ( n ) O(n) O(n)
代码:
自己写的繁琐的模拟代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int n = 10;
int a[10] = {2, 3, 3, 3, 5, 6, 6, 7, 7, 8};
bool cmp(int a, int b) {
return a > b;
}
int main() {
sort(a, a + n);
int ans = 0;
do {
bool ok = false;
for (int i = 0; i <= 7; i ++ ) {
for (int j = i + 1; j <= 8; j ++ ) {
if ((is_sorted(a, a+i+1) || is_sorted(a, a+i+1, cmp)) &&
(is_sorted(a+i+1, a+j+1) || is_sorted(a+i+1, a+j+1, cmp)) &&
(is_sorted(a+j+1, a+n) || is_sorted(a+j+1, a+n, cmp))) {
ok = true;
break;
}
}
if (ok) break;
}
if (ok) ans ++ ;
} while (next_permutation(a, a + n));
cout << ans << endl;
return 0;
}
dfs
判断三段有序序列,参考学习!俗称暴力~
#include <iostream>
#include <algorithm>
#include <unordered_set>
using namespace std;
int a[10] = {2, 3, 3, 3, 5, 6, 6, 7, 7, 8};
string get()
{
string s;
for(int i = 0;i < 10;i ++)
s += to_string(a[i]);
return s;
}
bool dfs(string& s, int u, int c)
{
if(c > 3) return false;
if(u >= 10 && c <= 3) return true;
int k = u;
while(k + 1 < 10 && a[k] <= a[k + 1]) k ++;
if(dfs(s, k +1, c + 1)) return true;
k = u;
while(k + 1 < 10 && a[k] >= a[k + 1]) k ++;
if(dfs(s, k + 1, c + 1)) return true;
return false;
}
int main()
{
unordered_set<string> S;
int res = 0;
do {
string s = get();
if(S.count(s) == 0)
{
// cout << s << endl;
if(dfs(s, 0, 0))
S.insert(s);
}
}while(next_permutation(a, a +10));
cout << S.size() << endl;
return 0;
}