码迷,mamicode.com
首页 > 其他好文 > 详细

NEFU559 分书问题【递归】

时间:2015-04-13 18:57:16      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=559


题目大意:

有编号分别为1~N的N本书,准备分给N个人,每个人阅读兴趣用一个二维数组表示。

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

Like[i][j] = 1,i喜欢书j;Like[i][j] = 1,i不喜欢书j。

问:如何分书才能使得所有人都满意,输出第i个人分得的书的编号,如果有多个答案

输出序列数小的那一组。


思路:

序列要求从小到大,那么就从小到大递归美剧每个人喜欢的书,找到第一组答案就可以

了。用vis[]数组来判断第i本书是否被选,ans[]数组来存储输出序列。从第一个人开始选

书,到最后一个人选完书,对于每个人,找出未被选、并且自己喜欢的书进行选择,并

用vis[]标记,将序列号存入ans[]数组。然后判断剩下的人是否满足人手一本的条件(递归

判断),如果不能则将vis[]还原(恢复现场),表示不能选择该书。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int Like[130][130],vis[130],ans[130],N;

int search(int M)
{
	if(M == N)
		return true;
	for(int i = 0;i < N; ++i)	//判断第i本书是否备选,第M个人是否喜欢第i本书 
	{
		if(!vis[i] && Like[M][i])
		{
			vis[i] = 1;			 
			ans[M] = i+1;		//第M个人选了第i本书 
			if(search(M+1))		//剩下的能否人手配一本,可以就返回 
				return 1;
			vis[i] = 0;			//不可以人手配一本,就不能选择第i本书(恢复现场) 
		}
	} 
	return 0;
} 
int main()
{
	while(~scanf("%d",&N))
	{
		for(int i = 0; i < N; ++i)
			for(int j = 0; j < N; ++j)
				scanf("%d",&Like[i][j]); 
		memset(vis,0,sizeof(vis));
		memset(ans,0,sizeof(ans));
		search(0);
		for(int i = 0; i < N; ++i)
			if(i != N-1)
				printf("%d ",ans[i]);
			else
				printf("%d\n",ans[i]);
	} 
	
	return 0;
} 



NEFU559 分书问题【递归】

标签:

原文地址:http://blog.csdn.net/lianai911/article/details/45029679

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!