• 每天算法一丁点(4)--递归算法应用:分书问题


    一道看似简单毫无头绪的问题   -_-||  

    题目:有编号分别为 1…n 的 n 本书,准备分给 n 个人,每个人阅读兴趣用一个二维数组加以描述,

        1:喜欢这本书      0: 不喜欢这本书

        like[i][j] = 1  , i 喜欢书 j

        like[i][j] = 0 , i 不喜欢书 j

        求解如何分书让所有人都满意

    n个人n本书。。。。

    分析:根据书上的解答,可以这么理解:

    如:

    6

    1 0 0 0 0 0     (喜欢第一本书,不喜欢第2,3,4,5,6本书)

    0 1 1 1 1 1

    1 1 0 0 0 0

    0 0 0 0 1 0

    1 1 0 0 1 1 

    1 0 1 0 0 0

    • 第一个人:我选第一本书,剩下的你们自己分配,可以人手一本吗?(递归层1)
    • 第二个人:我选第二本书,剩下的你们自己分配,可以人手一本吗?(递归层2)
    • 第三个人:不行!我只喜欢第一本和第二本,递归失败,返回递归层2(递归层3)
    • 第二个人:那我选第三本,剩下的你们自己分配,可以人手一本吗?(递归层2)
    • 第三个人:我选第二本书,剩下的你们自己分配,可以人手一本吗?(递归层3)
    • 第四个人:我选第五本书,剩下的你们自己分配,可以人手一本吗?(递归层4)
    • 第五个人:我选第六本书,剩下的你们自己分配,可以人手一本吗?(递归层5)
    • 第六个人:不行,我没喜欢的书了(递归层6)
    • 第五个人:不行,这样无法分配(递归层5)
    • 第四个人:不行,这样无法分配(递归层4)
    • 第三个人:不行,这样无法分配(递归层3)
    • 第二个人:那我选第四本,剩下的你们自己分配,可以人手一本吗?(递归层2)
    • 第三个人:我选第二本书,剩下的你们自己分配,可以人手一本吗?(递归层3)
    • 第四个人:我选第五本书,剩下的你们自己分配,可以人手一本吗?(递归层4)
    • 第五个人:我选第六本书,剩下的你们自己分配,可以人手一本吗?(递归层5)
    • 第六个人:我选第三本书,这样可以人手一本,递归结束(递归层6)

    虽然理解倒是不难,但是写起代码来真要命……    因为我的逻辑感真的不强。

    代码勉强写完,勉强弄明白,还需要回头多看看啊。。  真是为自己的未来担忧。。

    代码如下:(写下作为记录,抽空找个大佬给我捋一捋。。。)

    #include <iostream>
    using namespace std;
    
    #define N 550
    int like[N][N];             //  like[i][j]=1   第i个人喜欢第j本书(0表示不喜欢)
    int answer[N],n;            //  answer[m]=i    记录第m个人选择了第i本书
    bool selected[N];           //  selected[i]=1  第i本书已经被选(0表示没被选)
    
    bool search(int m){
        if( m == n){
            return true;
        }
        for(int i=0; i<n; i++){
            if( !selected[i] && like[m][i]){
                answer[m] = i+1;            //第m个人选择了第i本书;
                selected[i] = 1;
                if(search(m+1))
                    return true;            //第m+1个人没有喜欢的书了,退还第i本书
                selected[i] = 0;
            }
        }
        return false;
    }
    
    int main(){
        cout<<"-----选书开始----"<<endl;
        cout<<"请输入本次一共多少人:"<<endl;
        while(scanf("%d",&n)!=EOF){
            memset(selected,0,sizeof(selected));
            memset(answer,0,sizeof(answer));
            for(int i=0; i<n; i++){
                for(int j=0; j<n; j++){
                    printf("第%d个人是否喜欢第%d本书,喜欢1,不喜欢0:",i+1,j+1);
                    scanf("%d",&like[i][j]);
                    if(search(0)){
                        printf("第%d个人选择了第%d本书
    ",1,answer[0]);
                        for(int i=1; i<n; i++){
                            printf("第%d个人选择了第%d本书",i+1,answer[i]);
                            printf("
    ");
                        }
                    }
                }
            }
            cout<<"-----本轮结束-----"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    安全相关小知识
    http小知识
    跨域资源共享 CORS
    Django——CRSF攻击及处理
    Django——XSS攻击及处理
    Django——模版层(前后端交互编码方式,django模板使用的两种方式,模板语法之变量&深度查询句点符,模板渲染成标签还是原字符串,过滤器+自定义,标签+自定义)
    Django——Postman介绍及安装, 测试项目
    Django——视图层(请求&响应对象,cbv和fbv,文件上传)
    一个http请求从浏览器发出去,经历的过程(即上网流程)
    Django——有名分组 无名分组,反向解析,名称空间
  • 原文地址:https://www.cnblogs.com/yinniora/p/12109287.html
Copyright © 2020-2023  润新知