【C++】枚举

枚举算法

枚举算法的核心在于枚举每一种可能,并分别判断可行性

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 1ilen1的元素都满足
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[i1]=str[i+1]
所以,所有奇数位的数字和偶数位的数字都是相同的,所有可以直接枚举奇数位和偶数位的数值从而计算
最短的一定符合其中一个:

  1. ababababababab
  2. 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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值