算法学习之路

本文深入探讨了多种核心算法,包括递归求全排列、双向广度优先搜索、回溯算法、A*算法、数字Hash、二分法、0-1背包问题、枚举N选K方案等,提供了详细的实现思路与代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.用递归求n个数的全排列

int star[]={0,1,2,3,4,5,6,8,9,10,12};   //储存要排列的n个数,0不用
#define Swap(a,b) {int temp = a; a = b; b = temp;}  //交换
int num=0;     //统计全排列的个数
int Perm(int begin,int end)//求数组里begin到end的全排列
{
    int i;
    if(begin == end)    // 结束,输出一个全排列
         num++;  //统计全排列的个数;
    else
         for(i = begin;i <= end;i++)
         {
      	    Swap(star[begin],star[i]);//交换位置,逐步前提
      	    Perm(begin+1,end);
      	    Swap(star[begin],star[i]);//将位置还回去,对下一次排列负责
         }
}

求第n个全排列

int num[21] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
void change(int i, int j) {
	int tmp = num[i];
	num[i] = num[j];
	num[j] = tmp;
}
bool fun(int begin, int end){
	if (begin == end)    
		m--;  
	else if (m > 0) {
		for (int i = begin; i <= end; i++) {
			change(begin, i);
			if(fun(begin + 1, end))
				return true;
			change(begin, i);
		}
	}
	if (m == 0) {
		for (int i = 1; i <= n; i++) {
			printf("%d", num[i]);
			if (i != n) printf(" ");
		}
		return true;
	}
	return false;
}

2.双向广度优先搜索

3.回溯算法

4.A算法

5.转数字Hash

    用于不好比较的对象,如日期,坐标,字符串等。***本质是N进制的使用***

6.二分法的原理

    把时间值转换为二进制,用相应的二进制位的幂来表示十进制数,进而将时间复杂度为十进制的数分解成时间复杂度为二的指数(即n变为log n)

7.0-1背包

    DFS+DP+prun

// index 当前处理的物品编号,sumW 和 sumC 为当前总重量和总价值 
void DFS(int index, int sumW, int sumC) {
    if(index == n) {    // 已经把 n 件物品处理完毕(死胡同) 
        return; 
    }
    // 岔道口
    DFS(index+1, sumW, sumC);    // 不选 Index 号物品
    // 只有加入 index 物品后总重量小于 V 才可以继续 
    if(sumW + w[index] <= V) {
        if(sumC + c[index] > maxValue) {
            maxValue = sumC + c[index];
        }
        DFS(index+1, sumW+w[index], sumC+c[index]);    // 选 Index 号物品
    }
}

8.枚举N选K的所有方案

int n,k,x,maxSumSqu=-1,a[maxn];//maxSumSqu是最大平方和
vector<int> temp,ans;
void DFS(int index,int nowK,int sum,int sumSqu)
{
	if(nowK==K&&sum==X)
	{
		if(sumSqu>maxSumSqu)
		{
			maxSumSqu=sumSqu;
			ans=temp;
		}
		return;
	}
	if(index==n||nowK>K||sum>X)
		return;
	temp.push_back(a[index]); 
	DFS(index+1,nowK+1,sum+a[index],sumSqu+a[index]*a[index]);//选择了index 
	temp.pop_back();//删掉a[index] 
	DFS(index+1,nowK,sum,sumSqu);//不选index 
}

若N个整数中的每一个都可以被选择多次,应将选择了index改为

DFS(index,nowK + 1,sum + A[index],sumSqu + A[index]*A[index]);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值