栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

算

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

算

回溯法 N皇后
  • 循环迭代
#include 
#include 

#define N 4

//皇后摆放结果 的 统计数组,索引:代表行; 元素值:代表列
int q[N + 1];

// 同列、同斜线 检查
int check(int j)
{
	int i;
	// 从第1个到 j-1个, 依次 和 第j个皇后 比对
	for (i = 1; i < j; i++)
	{
		// q[i] == q[j] :  同列判断
		// abs(i-j) == abs(q[i] - q[j]): 同斜线判断
		
		if (q[i] == q[j] || fabs(i - j) == fabs(q[i] - q[j]))
		{
			return 0;
		}
	}

	return 1;
}

// 摆放 皇后
void queen()
{
	int i;
	// 皇后 数组 初始化
	for (i = 1; i <= N; i++)
		q[i] = 0;

	int answer = 0; // 方案数,用来 统计 能找出来 几种方案

	int j = 1; // 摆放 第j个皇后
	while (j >= 1)
	{
		// 让当前 皇后 向后一列 摆放
		q[j] += 1;

		// q[i]<=N 不能超出范围
		// !check(j) 同列、同斜线 返回 0,取反为 true
		while (q[j] <= N && !check(j))
		{
			// 摆放
			// 综上: 在范围内 若 皇后 同行or同斜线 则 向后一列 摆放
			q[j] += 1;
		}

		
		if (q[j] <= N) // 列数 判断
		{
			if (j == N) // 行数 判断
			{ // 找到 N皇后 的 一组解,
				answer = answer + 1;
				printf("第%d种方案 的 答案为:", answer);
				for (i = 1; i <= N; i++)
				{
					printf(" %d ", q[i]);
				}
				printf("回退回去 看看还能再找一组解吗 n");
			}
			else
			{
				j = j + 1; //放置 下一个 皇后;
			}
		}
		else
		{ // 当前行 的 皇后 没有合法的位置 需要 回溯 到 上一个皇后
			q[j] = 0;
			j = j - 1;
			if(j==0) {
				printf("找不到了,给 while 数一声,让他退出n");
			}
		}
	}
}

int main()
{
	queen();
	return 0;
}

  • 递归函数
#include 
#include 

#define N 4

int answer = 0; //方案数
int q[N + 1];	//皇后 数组

// 同列、同斜线 检查, 对于if来说 0-->false  非0--->true
int check(int j)
{
	int i;
	for (i = 1; i < j; i++)
		if (q[i] == q[j] || abs(i - j) == abs(q[i] - q[j]))
			return 0;

	return 1;
}

// 摆放 皇后
void queen(int j)
{
	int i;
	for (i = 1; i <= N; i++)
	{
		q[j] = i; // 放置一个位置

		

		if (check(j)) // check(j) 不但检验合法性,也是 递归 的 结束条件
		{ 
			if (j == N)
			{ // 找到一组解
				answer++;
				printf("第%d种方案 的 答案为:", answer);
				for (i = 1; i <= N; i++)
				{
					printf(" %d ", q[i]);
				}
				printf("n");
				// return;
			}
			else
			{
				queen(j + 1); // 递归摆放下一个 皇后 的位置
			}
		}
	}
}

int main()
{
	queen(1);
	return 0;
}

分治法 最大子段和
#include 

int MaxSubSum(int *Array, int left, int right)
{
	int res;

	// 一旦考虑用递归,就先写 递归限制条件!!!
	if (left == right)
	{
		res = Array[left] > 0 ? Array[left] : 0;
	}
	else
	{
		// 划分左右的 中间轴 索引
		int center = (left + right) / 2;
		// 左子递归,向左拆分, 可获取 左子段 的 最大子段和
		int leftsum = MaxSubSum(Array, left, center);
		// 右子递归,向右拆分, 可获取 右子段 的 最大子段和
		int rightsum = MaxSubSum(Array, center + 1, right);

		// 计算 总的子段和 = 左子段和 + 右子段和
		int i, tmp = 0, leftPart = 0; // leftPart 左子段和
		for (i = center; i >= left; i--)
		{
			tmp += Array[i];

			if (tmp > leftPart)
				leftPart = tmp;
		}

		tmp = 0;		   // 临时变量 重新使用 就需要 初始化一次
		int rightPart = 0; // rightPart 右子段和
		for (i = center + 1; i <= right; i++)
		{
			tmp += Array[i];
			if (tmp > rightPart)
				rightPart = tmp;
		}
		// 总的子段和
		res = leftPart + rightPart;

		// 三者比较 谁大 谁为 最大子段和
		if (leftsum > res)
			res = leftsum;

		if (rightsum > res)
			res = rightsum;
	}

	return res;
}

int main()
{
	int arr[6] = {-2, 11, -4, 13, -5, -2};
	int res;
	res = MaxSubSum(arr, 0, 5);
	printf("%d", res);
	return 0;
}

动态规划法 01背包
#include 

#define N 4 // 物品数量
#define W 5 // 背包容量

int max(int a, int b)
{
	return a > b ? a : b;
}
int main()
{
	int v[] = {0, 2, 4, 5, 6}; // 物品价值数组
	int w[] = {0, 1, 2, 3, 4}; // 物品重量数组

	int f[N + 1][W + 1] = {}; // 子问题 的 真值表

	int i, j; // i: 第i个物品, j:背包容量
	for (i = 1; i <= N; i++)
	{
		for (j = 1; j <= W; j++)
		{
			if (j >= w[i])
			{
				//能否使用 case1 的条件判断,即 第i个物品 的重量 小等 背包容量
				// case1 的 计算规则
				f[i][j] = v[i] + f[i - 1][j - w[i]];
				// 和 case2 的 计算规则  进行 比对 取最大值
				f[i][j] = f[i][j] > f[i - 1][j] ? f[i][j] : f[i - 1][j];
			}
			else
			{
				// case2 的 计算规则
				f[i][j] = f[i - 1][j]; 
			}
		}
	}

	// 将 最终 问题的解 打印出来
	printf("%dn", f[N][W]);

	return 0;
}

贪心法 部分背包
#include 

#define N 5	  // 物品数量
#define W 100 // 背包容量

// 部分背包 所能装载的 最大价值
// 调用前提: 已按照 单位总量价值 从大到小 排好序了
double MaxValue(int v[], int w[], double vw[])
{
	double curVals = 0.0; // 当前背包承载总价值
	int W_temp = W;		  // 背包容量

	int i;
	for (i = 1; i <= N; i++)
	{
		if (W_temp >= w[i])
		{
			W_temp = W_temp - w[i];	  //装入当前 物品
			curVals = curVals + v[i]; // 总价值 增加
		}
		else
		{
			// 容量 不够 装下一整个 物品的 时候 跳出循环
			break;
		}
	}

	// 如果 物品没装完,且 还有容量, 则 装入 部分物品
	if (i <= N && W_temp > 0)
		curVals = curVals + (double)W_temp / w[i] * v[i];
	
	return curVals;
}

int main()
{
	int v[] = {0, 65, 20, 30, 60, 40}; // 物品价值数组
	int w[] = {0, 30, 10, 20, 50, 40}; // 物品重量数组

	double vw[N + 1]; // 物品 单位重量 价值数组

	int i;
	for (i = 1; i <= N; i++)// 初始化 vw
		vw[i] = (double)v[i] / w[i];

	double res = MaxValue(v,w,vw);
	printf("%f n",  res);  // 163.000

	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/913232.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号