算法设计与分析实验共计四个实验,12段代码,篇幅原因,仅展示有代表性的两个,其余代码文末自取,有问题评论区留言。
目录
1.dp资源分配问题:
1.1代码:
#include <stdio.h>
#define MAX_SIZE 100
//m 项目数 n 总投资数 q利润表(由用户进行输入)
void AllocateResources(int m, int n, double q[MAX_SIZE][MAX_SIZE]) {
double f[MAX_SIZE]; // 存储最大利润
int a[MAX_SIZE][MAX_SIZE]; // 存储投资方案 第i个项目在总投资额为j时,当前项目所分配的投资额度
double temp[MAX_SIZE]; // 临时存储最大利润
int gain[MAX_SIZE]; // 存储每个项目的投资额
int rest; // 剩余的总投资额
for (int j = 0; j <= n; j++) {
f[j] = q[1][j]; // 初始化第一行的最大利润,只考虑第一个项目时的最大利润
a[1][j] = j; // 初始化第一行的投资方案,只考虑第一个项目时的投资方案
}
for (int k = 2; k <= m; k++) { // 动态规划求解最优解,k为项目编号(从第二个项目开始)
for (int j = 0; j <= n; j++) {
temp[j] = q[k][j]; // 初始化临时最大利润,确保在后续的计算中,考虑到当前项目的利润
a[k][j] = 0; // 初始化投资方案,表示在当前的状态下还没有确定具体的投资方案
}
for (int j = 0; j <= n; j++) { //遍历可能的总投资额j j为总投资额,i为当前项目投资额
for (int i = 0; i <= j; i++) { //遍历当前总投资额j下的所有投资额组合i
if (f[j - i] + q[k][i] > temp[j]) { // 如果当前方案的利润更大,则更新临时最大利润和投资方案
temp[j] = f[j - i] + q[k][i]; //q[k][i]为当前项目利润 f[j-i]为上一项目利润
a[k][j] = i; //保存最大投资额
}
}
}
for (int j = 0; j <= n; j++) {
f[j] = temp[j]; // 更新最大利润,把这轮计算的最新项目得出的最大利润加进利润表中
}
}
rest = n; // 初始化剩余总投资额
for (int i = m; i >= 1; i--) { // 根据最优解获取投资额和项目编号
gain[i] = a[i][rest]; //获取投资额记录
rest = rest - gain[i];
}
printf("项目编号\t投资额\n"); // 输出结果
for (int i = 1; i <= m; i++) {
printf("%d\t\t%d\n", i, gain[i]);
}
printf("-----------------------\n");
printf("最大利润\t%.3lf\n", f[n]);
}
int main() {
int m, n;
double q[MAX_SIZE][MAX_SIZE];
printf("请输入项目数 m:"); // 读取项目数和总投资数
scanf("%d", &m);
printf("请输入总投资数 n:");
scanf("%d", &n);
printf("请输入利润表:\n"); // 读取利润表
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
scanf("%lf", &q[i][j]);
}
}
AllocateResources(m, n, q); // 调用函数进行资源分配
return 0;
}
1.2测试用例:
//m=3 n=7
//利润表 q :
// 0.11 0.13 0.15 0.21 0.24 0.30 0.35
// 0.12 0.16 0.21 0.23 0.25 0.24 0.34
// 0.08 0.12 0.20 0.24 0.26 0.30 0.35
2.迷宫问题bfs:
2.1代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 8
typedef struct {
int x;
int y;
} Node;
int maze[MAX][MAX] = {
{0, 0, 0, 0, 0, 0, 0, 0}, // 迷宫布局
{0, 1, 1, 1, 1, 0, 1, 0},
{0, 0, 0, 0, 1, 0, 1, 0},
{0, 1, 0, 0, 0, 0, 1, 0},
{0, 1, 0, 1, 1, 0, 1, 0},
{0, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 0, 0, 1, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 0}
};
int vis[MAX][MAX]; // 记录节点是否被访问过
int px[MAX][MAX], py[MAX][MAX]; // 记录路径上的节点
int dx[] = {1, -1, 0, 0}; // 相邻节点的x坐标偏移量
int dy[] = {0, 0, 1, -1}; // 相邻节点的y坐标偏移量
// 广度优先搜索遍历迷宫
void bfs(int x, int y)
{
if (x == MAX - 1 && y == MAX - 1) // 到达终点
{
Node ans[MAX * MAX]; // 保存路径上的节点
int size = 0; // 路径长度
while (x != 0 || y != 0) // 从终点回溯到起点
{
ans[size].x = x; // 保存路径上的 x 坐标
ans[size].y = y; // 保存路径上的 y 坐标
size++;
int tx = px[x][y], ty = py[x][y];
x = tx, y = ty; // 回溯到上一个节点
}
printf("迷宫的一条路径:\n");
printf("(0,0)");
for (int i = size - 1; i >= 0; i--)
{
printf("->(%d,%d)", ans[i].x, ans[i].y); // 逆序输出路径上的坐标
}
printf("\n");
return;
}
vis[x][y] = 1; // 标记当前节点为已访问
for (int i = 0; i < 4; i++) // 遍历四个方向的相邻节点
{
int xx = x + dx[i], yy = y + dy[i]; // 计算相邻节点的坐标
if (xx >= 0 && xx < MAX && yy >= 0 && yy < MAX && !vis[xx][yy] && maze[xx][yy] != 1) // 判断相邻节点是否满足条件
{
px[xx][yy] = x; // 记录路径上的 x 坐标
py[xx][yy] = y; // 记录路径上的 y 坐标
bfs(xx, yy); // 递归访问相邻节点
}
}
}
// 打印带有路径的迷宫
void PrintMaze()
{
printf("迷宫路径可视化:\n");
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
if (maze[i][j] == 1) {
printf("* "); // 墙壁
} else if (i == 0 && j == 0) {
printf("S "); // 起点
} else if (i == MAX - 1 && j == MAX - 1) {
printf("E "); // 终点
} else {
int isPath = 0; // 是否为路径上的点
int x = MAX - 1, y = MAX - 1;
while (x != 0 || y != 0) {
if (px[x][y] == i && py[x][y] == j) {
printf("P "); // 路径上的点
isPath = 1;
break;
}
int tempX = px[x][y]; // 保存上一个节点的 x 坐标
int tempY = py[x][y]; // 保存上一个节点的 y 坐标
x = tempX; // 更新当前节点的 x 坐标为上一个节点的 x 坐标
y = tempY; // 更新当前节点的 y 坐标为上一个节点的 y 坐标
}
if (!isPath) {
printf("0 "); // 可行路径
}
}
}
printf("\n");
}
printf("\n");
}
int main() {
printf("迷宫:\n");
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
printf("%d ", maze[i][j]); // 打印迷宫的初始布局
}
printf("\n");
}
printf("\n");
memset(vis, 0, sizeof(vis)); // 将vis数组初始化为0,表示所有节点都未被访问过
memset(px, -1, sizeof(px)); // 将px数组初始化为-1,表示路径上的节点未被记录
memset(py, -1, sizeof(py)); // 将py数组初始化为-1,表示路径上的节点未被记录
bfs(0, 0); // 调用bfs函数开始遍历迷宫
printf("\n");
PrintMaze(); // 打印带有路径的迷宫
return 0;
}