aimisiyou 发表于 2020-10-28 08:20:33

排队问题

有24个高低不同的同学,现要排成三行,每一行从左到右由低到高,每一列从前到后也是由低到高。有多少种排法?

mathe 发表于 2020-10-28 09:04:29

应该是3192727797

northwolves 发表于 2020-10-28 10:22:02

每行人数相同还是允许不同?

aimisiyou 发表于 2020-10-28 10:57:42

northwolves 发表于 2020-10-28 10:22
每行人数相同还是允许不同?

每行人数相同啊

aimisiyou 发表于 2020-10-28 11:09:06

mathe 发表于 2020-10-28 09:04
应该是3192727797

除了暴力枚举法,还有什么简单算法

mathe 发表于 2020-10-28 12:00:41

动态规划

mathe 发表于 2020-10-28 12:03:29

将24个人依次从低到高排好位置,按前k个人使用掉的位置集合进行分类(不区分每个人的具体位置),递推各分类的人数即可

aimisiyou 发表于 2020-10-28 12:22:10

mathe 发表于 2020-10-28 12:03
将24个人依次从低到高排好位置,按前k个人使用掉的位置集合进行分类(不区分每个人的具体位置),递推各分类 ...

能写出DP公式吗?

mathe 发表于 2020-10-28 12:35:00


#include <map>
using namespace std;
typedef struct _PC{
    char cnt;
    bool operator<(const struct _PC& x)const{
        int i;
        for(i=0;i<3;i++){
          if(cnt<x.cnt)return true;
          if(cnt>x.cnt)return false;
        }
        return false;
    }
    bool operator==(const struct _PC& x)const{
        int i;
        for(i=0;i<3;i++){
          if(cnt!=x.cnt)return false;
        }
        return true;
    }
}PC;

typedef map<PC, long> PCMAP;

PCMAP pcmap0, pcmap1;
void add_data(PCMAP *next_map, const PC& data, long count)
{
    PCMAP::iterator it = next_map->find(data);
    if(it==next_map->end()){
        next_map->insert(std::make_pair(data, count));
    }else{
        it->second+=count;
        if(it->second<0L){
                printf("overflow\n");
        }
    }
}

#define N 8
int main()
{
    PCMAP *prev, *next, *tmp;
    int i;
    prev=&pcmap0;
    next=&pcmap1;
    PC pc;
    pc.cnt=1;pc.cnt=pc.cnt=0;
    prev->insert(std::make_pair(pc, 1L));
    for(i=2;i<=3*N;i++){
        next->clear();
        PCMAP::iterator it;
        for(it=prev->begin();it!=prev->end();++it){
          const PC& orig = it->first;
          PC update = orig;
            if(update.cnt<N){
             update.cnt++;
             add_data(next, update, it->second);
            }
          if(orig.cnt>orig.cnt){
                update=orig;
                update.cnt++;
                add_data(next,update, it->second);
          }
          if(orig.cnt>orig.cnt){
                update=orig;
                update.cnt++;
                add_data(next,update, it->second);
          }
        }
        tmp=prev;
        prev=next;
        next=tmp;
    }
    long sum = 0;
    PCMAP::iterator it;
    for(it=prev->begin();it!=prev->end();++it){ sum+=it->second;}
    printf("Total %ld\n",sum);
}

aimisiyou 发表于 2020-10-28 12:49:34

进而推到一般情况,m行n列,求通项公式F(m,n).显然有F(m,n)=F(n,m)。F(1,n)=F(n,1)=1,F(2,n)=F(n,2)=C(2n,n)/(n+1)(卡特兰数)
F(3,n)=?
F(m,n)=?
页: [1] 2
查看完整版本: 排队问题