枚举算法
枚举算法的核心在于枚举每一种可能,并分别判断可行性
for循环
利用for依次枚举每一种可能,并进行判断
例如:查找
a
a
a数组中的最小值
ans=INF;
for(int i=1;i<=10;i++)
ans=min(a[i],ans);
递归枚举
即为深度优先搜索DFS
例如:在
a
a
a数组中选择k个元素使其和的结果为3的倍数且尽可能的大
void dfs(int cnt, int sum, int idx) {
if(cnt == k) {
if(sum%3 != 0) {
ans = max(ans, sum);
}
return;
}
dfs(cnt+1, sum+a[idx], idx+1); // 选
dfs(cnt, sum, idx+1); // 不选
}
二进制枚举
可以用二进制的数字表示,例如1表示选择当前的 a i a_i ai,0则表示不选择当前的 a i a_i ai,通常与状态压缩 D P DP DP同时使用
枚举全排列
方法一
next_permutation(a,a+n)
方法二
用dfs
例题:循环
题面
思路
分析可以发现,最后的结果任何一个
1
≤
i
≤
l
e
n
−
1
1≤i≤len-1
1≤i≤len−1的元素都满足
s
t
r
[
i
[
]
=
s
t
r
[
i
−
1
]
=
s
t
r
[
i
+
1
]
str[i[]=str[i-1]=str[i+1]
str[i[]=str[i−1]=str[i+1]
所以,所有奇数位的数字和偶数位的数字都是相同的,所有可以直接枚举奇数位和偶数位的数值从而计算
最短的一定符合其中一个:
- ababababababab
- aaaaaaaaaaaaaa
当所有位置的数字都相同的情况
for (int i = 0; i < len; i++) {
cnt[str[i]-'0']++;
}
for (int i = 0; i <= 9; i++) {
ans=max(ans,cnt[i]);
}
当前满足ababab……的情况
枚举的a和b应该满足不相同,否则就和上一种情况一模一样了
for (int i = 0; i <= 9; i++) {
for (int j = 0; j <= 9; j++) {
if (i != j) {
ans = max(ans, solve(i, j));
}
}
}
计算当前最长的满足ababab……形式的子序列
int solve(int a, int b) {
int len = str.size();
int flag = 0, siz = 0;
for (int i = 0; i < len; i++) {
if(str[i]-'0'==a){
flag=0;
for(int j=i+1;j<len && flag==0;j++){
if(str[j]-'0'==b){
i=j;
siz++;
flag=1;
}
}
}
}
return siz*2;
}
实现代码
最后需要特别注意,至少序列中还剩两个数字,不要忘了初始化,最后的结果就是len-ans
#include <bits/stdc++.h>
using namespace std;
string str;
int cnt[10];
int solve(int a, int b) {
int len = str.size();
int flag = 0, siz = 0;
for (int i = 0; i < len; i++) {
if(str[i]-'0'==a){
flag=0;
for(int j=i+1;j<len && flag==0;j++){
if(str[j]-'0'==b){
i=j;
siz++;
flag=1;
}
}
}
}
return siz*2;
}
int main() {
cin >> str;
int len = str.size();
int ans = 2;
for (int i = 0; i < len; i++) {
cnt[str[i]-'0']++;
}
for (int i = 0; i <= 9; i++) {
ans=max(ans,cnt[i]);
}
for (int i = 0; i <= 9; i++) {
for (int j = 0; j <= 9; j++) {
if (i != j) {
ans = max(ans, solve(i, j));
}
}
}
cout << len-ans << endl;
return 0;
}