zoukankan      html  css  js  c++  java
  • 每天算法一丁点(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;
    }
  • 相关阅读:
    redis 储存对象
    redis key 查看器
    c# 控制台程序编写RabbitMQ 生产者
    C# 使用Topshelf 构建 基于 window 服务的 RabbitMQ消费端
    asp.net webapi 使用定时任务Hangfire
    asp.net webpi 中使用 ClientHelper 发起HTTP请求
    SQL Server 导入和导出向导 未在本地计算机上注册Mircrosoft.ACE.OLEDB.12.0 提供程序
    c# 使用Linq 表达式 对查询结果分组,保留价格最低的一条
    Asp.Net s请求报传输流收到意外的 EOF 或 0 个字节
    asp.net webapi 中使用rdlc 报表
  • 原文地址:https://www.cnblogs.com/yinniora/p/12109287.html
Copyright © 2011-2022 走看看