DFS进阶——分考场

分考场(较难)
题目分析

这个题目稍微难一点,我们要为n个考生分配考场,那么我每次要考虑的是对于第x个考生,我要给他安排在哪一个考场里面,那么我还需要知道我当前使用了哪些考场,并且这些考场里面被安排了哪些考生。我们还要知道哪些考生之间认识。一个一个来解决,设一个数组map[i][j],如果值为1表示编号为i和编号为j的考生认识,否则就是不认识。设一个变量cnt表示当前我已经使用的考场的个数。设一个数组room[i][j]=k表示在第i个考场里的第j个学生的编号为k。

接下来考虑dfs的过程。x表示当前要安排第x个考生,当前使用的考场数为cnt个

static void dfs(int x, int cnt)

接下来是剪枝,如果当前使用的考场数超过了我之前记录的最小考场数,那么后面就不用遍历了,

if(cnt>=min) return;

然后是终点判断,当n个人都遍历完时,也就是x到了n+1我要看当前使用的考场数是否比我之前记录的最小考场数还小

if(x==n+1){
   
    min = Math.min(min,cnt);
    return;
}

接下来就是安排考场了,考虑把第x个考生安排在第j个考场,j的取值从1到cnt。那么我要判断,第j个考场的所有人是否有和第x个考生认识的。如果room[j][k]!=0表示第j个考场有第k个考生,并且它的编号是room[j][k],那么我们要判断这个考生和第x个考生是否认识,即map[x][room[j][k]]==0表示他们不认识。

int j,k;
for(j=1; j<=cnt; j++){
   
    k=1;
    while(room[j][k]!=0 && map[x][room[j][k]]==0){
   
        k++;
    }
    ....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值