作者:mobiledu2502858407 | 来源:互联网 | 2024-11-09 20:10
题目解析给定n个人和n种书籍,每个人都有一个包含自己喜好的书籍列表。目标是计算出满足以下条件的分配方案数量:1.每个人都必须获得他们喜欢的书籍;2.每本书只能分配给一个人。通过使用深度优先搜索算法,可以系统地探索所有可能的分配组合,确保每个分配方案都符合上述条件。该方法能够有效地处理这类组合优化问题,找到所有可行的解。
题意分析 现有n个人,n种书,给出每人对n种书的喜欢列表,求有多少种方案满足以下条件:
1.每个人都分得自己喜欢的书; 2.每个人分得书的种类各不相同,即所有种类的书均得到分配
1.采用生成测试法 生成过程 对于每个人来说,枚举每本书的状态(0/1),有2^20; 最多有20个人 ,则有20*2^20 = 10*2^21 ≈ 10^3 * 10 ^3 * 10 = 10^ 7 考虑上测试的时间,TLE。
2.优化 充分利用题目中给的信息,即每个人对不同书的喜爱我们是已知的。对于每个人来说,我们不需要枚举全部书籍的状态,只需要枚举他喜爱的每本书的状态,即从他喜欢的书籍中选一本给他,然后再看下一个人,再从这个人喜爱的书籍中选一本给他…… 直到所有人都分得书籍。然后再检查是否所有的书籍都得到分配,若是,ans++,否则继续枚举下一种分配情况。
代码总览 #include #include #include #include #include #include #include #include #include #include #define INF 0x3f3f3f3f #define nmax 25 #define MEM(x) memset(x,0,sizeof(x)) using namespace std ;vector <int > v[nmax];bool bookvisit[nmax];bool peoplevisit[nmax];int ans &#61; 0 ,n;bool check() {for (int i &#61; 0 ; iif(!bookvisit[i] || !peoplevisit[i])return false ;}return true ; }void dfs(int peo) {if (peo &#61;&#61; n){if (check()) ans&#43;&#43;;return ;}peoplevisit[peo] &#61; true ;for (int i &#61; 0 ; iif(!bookvisit[v[peo][i]]){bookvisit[v[peo][i]] &#61; true ;dfs(peo&#43;1 );bookvisit[v[peo][i]] &#61; false ;}} }void init() {MEM(peoplevisit);MEM(bookvisit);ans &#61; 0 ; }int main() {char str[nmax];while (scanf ("%d" ,&n)!&#61; EOF){init();for (int i &#61;0 ;iscanf("%s" ,str);for (int j &#61; 0 ;j<strlen (str);&#43;&#43;j)if (str[j] &#61;&#61; &#39;1&#39; ) v[i].push_back(j);}dfs(0 );printf ("%d\n" ,ans);}return 0 ; }