算法设计与分析实验报告-递归与分治策略

本文介绍了北京大学算法设计与分析实验报告中的部分内容,包括递归解决问题、分治策略在求偶数个数和棋盘覆盖中的应用,以及动态规划、贪心算法和Dijkstra算法的基本概念。实验通过实例展示了如何使用这些策略解决问题。
摘要由CSDN通过智能技术生成

校课程的简单实验报告。

算法设计与分析实验报告-递归与分治策略

算法设计与分析实验报告-动态规划算法

算法设计与分析实验报告-贪心算法 

        dijkstra迪杰斯特拉算法(邻接表法)

算法设计与分析实验报告-回溯法

算法设计与分析实验报告-分支限界法 

算法设计与分析实验报告-分治法相关练题

北京大学出版社-算法设计与分析


目录

一、实验目的

二、实验内容

三、实验环境

四、实验步骤及说明

五、实验小结及思考


一、实验目的

    1.掌握利用递归解决问题的几个要素;

    2.理解分治策略的原理、步骤及特征;

    3.掌握利用分治策略解决查找问题;

    4.掌握利用分治策略解决组合问题。

二、实验内容

使用递归与分治法求解以下问题,要求给出程序代码,并编译运行程序:

1.求输入整数集合中元素值为偶数的元素个数。

2.求解8*8的棋盘覆盖。棋盘的特殊方格打印为“*”,普通方格打印为“.”。

三、实验环境

1. 使用的操作系统及版本:

Windows 10

  1. 使用的编译系统及版本:

CLion 2022.2.3

四、实验步骤及说明

1输入整数集合中元素值为偶数的元素个数。

代码如下:

//
// Created by GiperHsiue on 2022/10/17.
//
// 分治法求某集合中元素值为偶数的元素个数。
#include <iostream>
using namespace std;
int check(int arr[], int l, int r){
    if(l == r) return arr[l] % 2 ? 0 : 1;
    int mid = l + r >> 1;
    return check(arr, l, mid) + check(arr, mid + 1, r);
}
int main(){
    int n;
    cin >> n;
    int *arr = new int[n];
    for(int i = 0; i < n; i ++) cin >> arr[i];
    cout << check(arr, 0, n - 1);
    return 0;
}

测试如下:

  1. 求解8*8的棋盘覆盖。棋盘的特殊方格打印为“*”,普通方格打印为“.”,骨牌用数字编号表示。

代码如下:

//
// Created by GiperHsiue on 2022/10/20.
//
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
char tile = '1'; // 骨牌的编号
char **board;
//(r,c)棋盘左上角坐标,(sr,sc)特殊方格坐标,size棋盘的行(列)数
void cb(int r, int c, int sr, int sc, int size){
    if(size == 1) return;
    int t = tile++;
    int s = size / 2;

    //左上角
    if(sr < r + s && sc < c + s){
        cb(r, c, sr, sc, s);
    } else{
        board[r + s -1][c + s - 1] = t;
        cb(r, c, r + s - 1, c + s - 1, s);
    }

    //右上角
    if(sr < r + s && sc >= c + s){
        cb(r, c + s, sr, sc, s);
    } else{
        board[r + s -1][c + s] = t;
        cb(r, c + s, r + s - 1, c + s, s);
    }

    //左下角
    if(sr >= r + s && sc < c + s){
        cb(r + s, c, sr, sc, s);
    } else{
        board[r + s][c + s - 1] = t;
        cb(r + s, c, r + s, c + s - 1, s);
    }

    //右下角
    if(sr >= r + s && sc >= c + s){
        cb(r + s, c + s, sr, sc, s);
    } else{
        board[r + s][c + s] = t;
        cb(r + s, c + s, r + s, c + s, s);
    }
}
int main(){
    int k;
    cout << "棋盘大小2^k * 2^k 输入K:";
    cin >> k;
    int n = pow(2, k);
    board = new char*[n]; //动态创建棋盘数组
    for(int i = 0; i < n; i ++) board[i] = new char[n];
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            board[i][j] = '.';
        }
    }
    cout << "输入特殊方格位置:";
    int sr, sc;
    cin >> sr >> sc;
    board[sr][sc] = '*';
    cout << "初始化:" << endl;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cout << setw(4) << board[i][j];
        }
        cout << endl;
    }
    cb(0, 0, sr, sc, n);
    cout << "覆盖后:" << endl;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if(i == sr && j == sc) cout << setw(4) << board[i][j];
            else cout << setw(4) << board[i][j] - '0';
        }
        cout << endl;
    }
    return 0;
}
 

测试如下:


五、实验小结及思考

通过本次实验,让我对于递归解决问题有了进一步的认识。分治策略是对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同。递归地解这些子问题,然后将各子问题的解合并得到原问题的解。分治法在每一层递归上都有三个步骤:分解,将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;解决,若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题;合并,将各个子问题的解合并为原问题的解。

  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值