题目链接:http://codeforces.com/problemset/problem/140/B
题目意思:给出 Alexander 和他的 n 个朋友的 preference lists:数字 1~n 的排列。现在Alexander 需要遵循两条rules向他的 朋友发送贺卡。
1、他不会send 和 该朋友给他的一模一样的贺卡。
2、对于当前他所拥有的贺卡,他只会选择他自己最喜欢的卡给朋友。
同一张卡可以使用多次,而且尽量使得他的朋友满意,也就是尽量满足该朋友的 preference lists。
现在需要找出一条 send card 的 schedule,表示某个 moment 下应该send card 到某个friend中。
正如题解所说,这条题目难就难在模拟上。因为Alexander 某个时刻的决策受到两个因素的影响:他自己本人的preference list 以及他朋友的preference list 的影响。而且 Alexander 的preference list 随着时间的推移是有所改变的。所以我们希望在尽量不使得他朋友的preference list 太差的情况下,按照题目所说的,运用那两条rule.
排除 send 同 receive 是同 一 张卡并不困难,因为 编号为 i 的人send card 的时刻正是 i ,也就是编号为 i 的卡!不等于 i 即可。然后就是考虑对该朋友应该send 哪张卡了:对朋友的preference list 的每个数都check 下 Alexander 的preference list 中哪个数可以派发。(说不下去了,以下是请教乌冬子后整理的)
引用如下(白话文,请见谅),思路代码都非常清晰!
/*****************************
对于每个朋友,都枚举出所有alex可能发出既卡片,然后从中选出呢个朋友比较中意既就得
其实喜爱列表作用就系话比我地知,有滴卡系永远唔会寄出去
我地用朋友既角度去捻,最好既结果就系拿到alex可能寄出卡里面,自己最喜爱果张
注意到alex可以系任何时刻发卡片,所以枚举可能寄出卡片方法就系求出alex每日会寄出既卡片就得,因为有rule2所以我地要针对每个人求,例如,第一个例子,对于朋友1,alex每日寄出既卡系0,2,3,3,3,对于朋友2,每日寄出既卡片系1,1,3,3,3,朋友3系1,1,3,3,3 如此类推
********************************/
他的代码,就是按这个思路写的,我改了下下标,省去了一些处理,命名也改了下。
1 #include <cstdlib> 2 #include <cstdio> 3 #include <iostream> 4 #include <vector> 5 using namespace std; 6 7 const int N = 3e2 + 10; 8 9 int n, fri_pref[N][N]; 10 11 int main() 12 { 13 cin.sync_with_stdio(0); 14 while (cin >> n) { 15 for (int i = 1; i <= n; i++) 16 for (int j = 1; j <= n; j++) { 17 cin >> fri_pref[i][j]; 18 } 19 20 int Alex_pref[N]; 21 for (int i = 1; i <= n; i++) { 22 int input; 23 cin >> input; 24 Alex_pref[input] = i; // 标出Alex表的喜好编号顺序 25 } 26 27 int res[N]; 28 for (int i = 1; i <= n; i++) // 29 { 30 bool h[N] = {false}; 31 int now = -1; 32 for (int j = 1; j <= n; j++) // Alex 表 33 { 34 if (j == i || (~now && Alex_pref[j] > Alex_pref[now])) // ~now 即 now != -1,枚举Alex每日对i这个人寄出的卡片,且排除了Alex一定派不出去的卡 35 continue; 36 now = j; 37 h[now] = true; 38 } 39 40 for (int j = 1; j <= n; j++) 41 { 42 if (!h[fri_pref[i][j]]) 43 continue; 44 res[i] = fri_pref[i][j]; 45 break; 46 } 47 } 48 49 for (int i = 1; i < n; i++) 50 cout << res[i] << " "; 51 cout << res[n] << endl; 52 } 53 54 return 0; 55 }