poj 3487 http://poj.org/problem?id=3487
题目大意:
现在有n个男士,n个女士,他们要组合家庭
每一个男士都对每一位女士有一个喜好值,同样每一个女士对每一个男士也有一个喜好值
现在要求一种组合方式,让婚姻稳定!
怎样才能稳定呢??如果存在一个男士和一位女士,他们不是夫妻,但是对对方的喜好度都大于现在的伴侣,那么这个婚姻是不稳定的,容易理解吧
那么怎样才能使婚姻稳定呢??
这个是数学界切切实实研究过的问题,而且现在有了好多的应用,下面介绍一下算法的实现,然后分析一个很有意思的结论“
下面就是求婚了
第一天上午, 所有的男人都向自己最爱的女人求婚.下午, 每个女人看看自己有没有收到, 收到了多少人的求婚. 如果只收到一个男人的求婚, 那么就和他订婚. 如果收到多于一个男人的求婚, 那么就和其中她最爱的那个男人订婚, 同时把其他男人都锯掉. 如果一个求婚都没有, 不要着急, 最后总会有的.晚上, 检查一遍, 如果所有女人都订婚了, OK, 万事大吉, 明天举行集体婚礼.但如果还有女人没有订婚, 那么事情还没有完, 第二天还得重复.第二天上午, 所有还没订婚的男人向自己次爱的女人求婚(因为昨天已经被他们的最爱锯了).下午, 每个女人再看一遍自己收到订婚的情况. 如果她已经订婚了, 但是又有一个她更爱的男人来向她求婚, 那就把原来那个锯掉, 再和这个更爱的男人订婚; 如果还没订婚, 那就和第一天的下午的处理一样.晚上再检查一遍, 如果还是有人没有订婚, 那第三天再重复.第三天上午, 所有没有订婚的男人, 包括第一天订了第二天又被踹出来的, 再向还没有锯过他的女人中他最爱的那个求婚
...
如此周而复始, 直到最后大家都订了婚, 便一起结婚.
第一天上午, 所有的男人都向自己最爱的女人求婚.下午, 每个女人看看自己有没有收到, 收到了多少人的求婚. 如果只收到一个男人的求婚, 那么就和他订婚. 如果收到多于一个男人的求婚, 那么就和其中她最爱的那个男人订婚, 同时把其他男人都锯掉. 如果一个求婚都没有, 不要着急, 最后总会有的.晚上, 检查一遍, 如果所有女人都订婚了, OK, 万事大吉, 明天举行集体婚礼.但如果还有女人没有订婚, 那么事情还没有完, 第二天还得重复.第二天上午, 所有还没订婚的男人向自己次爱的女人求婚(因为昨天已经被他们的最爱锯了).下午, 每个女人再看一遍自己收到订婚的情况. 如果她已经订婚了, 但是又有一个她更爱的男人来向她求婚, 那就把原来那个锯掉, 再和这个更爱的男人订婚; 如果还没订婚, 那就和第一天的下午的处理一样.晚上再检查一遍, 如果还是有人没有订婚, 那第三天再重复.第三天上午, 所有没有订婚的男人, 包括第一天订了第二天又被踹出来的, 再向还没有锯过他的女人中他最爱的那个求婚
...
如此周而复始, 直到最后大家都订了婚, 便一起结婚.
上面的算法就可以求出一个稳定的婚姻了,下面介绍几个数学上证明的结论:
第一, 这个过程会中止, 也就是说, 总有大家都订了婚的一天,不可能无限循环.
第二, 中止后所有的婚姻是稳定婚姻。
第三, 比较引人注目的是, 这个过程是male-optimal的, 男性能够获得尽可能好的伴侣, 比如说最后有二十个女人拒绝了他,他仍然能够得到剩下的八十个女人中他最爱的那一个.
第四, 更有甚者, 这个过程是female-pessimal的, 女人总是在可能的情况下被最不喜欢的人追上. 这一点没有那么直观的理解, 勉强要解释的话, 可以这么看: 虽说女人每换一次订婚对象, 都往上升一层, 但起点可能很低, 虽说在一步步接近她最爱的目标, 但最后往往达不到. 比如说还差三十名就达到她最爱的人了, 但这时Game Over, 所有的人都已订了婚, 这样她也只能死了心了. 还有三十个她更爱的人还没向她求过婚,可是她也无可奈何了...
第二, 中止后所有的婚姻是稳定婚姻。
第三, 比较引人注目的是, 这个过程是male-optimal的, 男性能够获得尽可能好的伴侣, 比如说最后有二十个女人拒绝了他,他仍然能够得到剩下的八十个女人中他最爱的那一个.
第四, 更有甚者, 这个过程是female-pessimal的, 女人总是在可能的情况下被最不喜欢的人追上. 这一点没有那么直观的理解, 勉强要解释的话, 可以这么看: 虽说女人每换一次订婚对象, 都往上升一层, 但起点可能很低, 虽说在一步步接近她最爱的目标, 但最后往往达不到. 比如说还差三十名就达到她最爱的人了, 但这时Game Over, 所有的人都已订了婚, 这样她也只能死了心了. 还有三十个她更爱的人还没向她求过婚,可是她也无可奈何了...
哈哈,上面的第二和第三点很有意思,原来是这样啊。女同志不要愤怒哈,这个是数学上证明了的,当然这个只是个数学模型,但是挺好玩的,可能有人会问,数学家就那么无聊么?研究这样的问题??其实这个问题现在确实有着很多的应用,很多的资料都这么说的。
ps:不管男生还是女生,如果遇到喜欢的,那就赶紧表白吧,即使被拒了,你还是可以找到一个相对较适合你的,被动的话可能可能有更好的机会你错过了。哈哈,纯属个人观点,
!欢迎拍砖……
另:附上poj 3487代码
![](http://cnc.qzs.qq.com/qzone/em/e112.gif)
另:附上poj 3487代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define N 27
int libman[N][N],man[N],ladyscore[N][N],lady[N];
int main()
{
int cas,n,a[N];
stack<int> freeman;
string list;
char temp;
cin>>cas;
while(cas--)
{
while(!freeman.empty()) freeman.pop();
cin>>n;
for(int i=0; i<n; i++)
{
cin>>temp;
a[i]=temp-'a';
freeman.push(a[i]);
}
sort(a,a+n);
for(int i=0; i<n; i++) cin>>temp;
for(int i=0; i<n; i++)
{
cin>>list;
for(int j=0; j<n; j++)
libman[i][j]=list[j+2]-'A';
}
for(int i=0; i<n; i++)
{
cin>>list;
for(int j=0; j<n; j++)
ladyscore[i][list[j+2]-'a']=n-j;
}
for(int i=0; i<n; i++)
ladyscore[i][n]=0;//对"不存在"的男生打最低分 这个是??
memset(man,0,sizeof(man));
for(int i=0; i<N; i++) lady[i]=n; //这里不能用memset()因为n是变量而不是常数
int male,female;
while(!freeman.empty())
{
male=freeman.top();
female=libman[male][man[male]];
if(ladyscore[female][male]>ladyscore[female][lady[female]])
{
freeman.pop();
if(lady[female]!=n)
{
freeman.push(lady[female]);
man[lady[female]]++;
}
lady[female]=male;
}
else if(ladyscore[female][male]<ladyscore[female][lady[female]])
man[male]++;
}
for(int i=0; i<n; i++)
printf("%c %c\n",a[i]+'a',libman[a[i]][man[a[i]]]+'A');
if(cas != 0) printf("\n");
}
return 0;
}