單迴圈賽,每個隊參加前後兩場比賽之間的距離最大,這就是這個問題的要求。
這個問題,使用簡單回溯,剪剪枝好像可以,但是要當n很大的時候就很為難,速度什麼的成了問題。所以這裡,我使用了近似演算法。
觀察問題,發現這是一個對稱矩陣的問題,那麼我有幾條啟發學習法規則:
(1)插入矩陣的元素,不應該和前 m 的元素同行很列。
這個,很簡單可以理解,這是為了使最小間距得意保證。
(2)插入的位置,應儘可能在行或者列上佔據更多的空格。
這個,有一點難理解,主要是先插入的元素理應佔有利位置,這樣越往後,差距變大的可能性就提高了。
否則當後面插入時,差距就會變小
(3)插入位置理應和個行列產生最大的行間距。
這個也好理解,主要是為了保證最小間距最大。
(4)插入位置理應靠近上三角的中心。
這個還是為了保證插入時能很有效滿意。
之後,我們便是不斷地嘗試(1)裡面提到的m的值。這裡,我們先來估計一下m的上界吧。假設最小間距為m,那麼(i,j) 先比賽,比賽之後就是(i,k)比賽,這樣必須除了i,j,k之外還至少有2m個球隊,所以 n >= 2m + 3;也就是 m <= [(n-3)/2];
這樣,我們便開始從m的上界開始,向下檢索。
#include "stdafx.h"<br />#include <iostream><br />#include <vector><br />#include <algorithm><br />#include <cmath><br />using namespace std;<br />class class_last_one<br />{<br />private:<br />const int MAX_USE;<br />vector<vector<int>> matrix;<br />int n;<br />private:<br />double get_min_weight(int pos_i,int pos_j,int val)<br />{<br />double re = 0.0;<br />for(int cnt_i=0;cnt_i<n;cnt_i++)<br />{<br />for(int cnt_j=0;cnt_j<n;cnt_j++)<br />{<br />if (matrix[cnt_i][cnt_j] != MAX_USE && matrix[cnt_i][cnt_j] != 0)<br />{<br />re += (abs(cnt_i - pos_i) + abs(cnt_j - pos_j))*(val - matrix[cnt_i][cnt_j]);<br />}<br />}<br />}<br />return re;<br />}<br />int get_min_dis_for_each_form_zero(int pos_i,int pos_j,int val)<br />{<br />int re = 0;<br />for(int cnt=0;cnt<n;cnt++)<br />{<br />if (matrix[pos_i][cnt] <= n && matrix[pos_i][cnt] !=0 )<br />re += val - matrix[pos_i][cnt];<br />}<br />for(int cnt=0;cnt<n;cnt++)<br />{<br />if (matrix[cnt][pos_j] <= n && matrix[cnt][pos_j] !=0 )<br />re += val - matrix[cnt][pos_j] ;<br />}<br />return re;<br />}<br />int get_min_dis_for_each(int pos_i,int pos_j,int val)<br />{<br />int re = 0;<br />for(int cnt=pos_i;cnt<pos_j;cnt++)<br />{<br />if (matrix[pos_j][cnt] <= n && matrix[pos_j][cnt] !=0 )<br />re += val - matrix[pos_j][cnt];<br />}<br />for(int cnt=pos_j;cnt<n;cnt++)<br />{<br />if (matrix[pos_j][cnt] <= n && matrix[pos_j][cnt] !=0 )<br />re += val - matrix[pos_j][cnt] ;<br />}<br />return re;<br />}<br />int get_min_dis(int pos_i,int pos_j,int val)<br />{<br />if (pos_i<mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js"></mce:script><mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js"></mce:script> == pos_j)<br />return MAX_USE;<br />int re = MAX_USE;<br />for(int cnt=0;cnt<n;cnt++)<br />{<br />if (matrix[pos_i][cnt] <= n && matrix[pos_i][cnt] !=0 && val - matrix[pos_i][cnt] < re)<br />re = val - matrix[pos_i][cnt];<br />}<br />for(int cnt=0;cnt<n;cnt++)<br />{<br />if (matrix[cnt][pos_j] <= n && matrix[cnt][pos_j] !=0 && val - matrix[cnt][pos_j] < re)<br />re = val - matrix[cnt][pos_j];<br />}<br />return re;<br />}<br />int get_space(int pos_i,int pos_j)<br />{<br />if (pos_i == pos_j)<br />return 0;<br />int re = 0;<br />for(int cnt=0;cnt<n;cnt++)<br />{<br />if (matrix[pos_i][cnt] == 0)<br />re++;<br />}<br />for(int cnt=0;cnt<n;cnt++)<br />{<br />if (matrix[cnt][pos_j] == 0)<br />re++;<br />}<br />return re;<br />}<br />int get_dis_from_center(int pos_i,int pos_j)<br />{<br />return abs(pos_i - n/3) + abs(pos_j - 2*n/3);<br />}<br />bool set_matrix(int n_pre)<br />{<br />init_matrix();<br />vector<int> pos_pre;<br />vector<bool> b_larger;<br />b_larger.push_back(true);<br />b_larger.push_back(true);<br />b_larger.push_back(false);<br />vector<int> vct_cur(3);<br />vector<int> vct_use(3);<br />for(int cnt=1;cnt<=n*(n-1)/2;cnt++)<br />{</p><p>vct_use[0] = (-1); //space<br />vct_use[1] = (-1); //dis<br />vct_use[2] = (MAX_USE);//center<br />int pos_do_i = -1;<br />int pos_do_j = -1;<br />for(int pos_i=0;pos_i<n;pos_i++)<br />{<br />for(int pos_j=pos_i+1;pos_j<n;pos_j++)<br />{<br />if (matrix[pos_i][pos_j] != 0)<br />continue;<br />bool b_continue = false;<br />for(int cnt_k=2*n_pre;cnt_k >0 && pos_pre.size() > n_pre*2 - cnt_k;cnt_k--)<br />{<br />if (pos_i == pos_pre[pos_pre.size() -1 - 2*n_pre + cnt_k] || pos_j == pos_pre[pos_pre.size() -1 - 2*n_pre + cnt_k])<br />{<br />b_continue = true;<br />break;<br />}<br />}<br />if (b_continue == true)<br />continue;<br />vct_cur[0] = get_space(pos_i,pos_j);<br />vct_cur[1] = get_min_dis_for_each_form_zero(pos_i,pos_j,cnt);<br />vct_cur[2] = get_dis_from_center(pos_i,pos_j);<br />if (check_record_for_diff_weight(vct_cur,vct_use,b_larger))<br />{<br />vct_use = vct_cur;<br />pos_do_i = pos_i;<br />pos_do_j = pos_j;<br />}<br />}<br />}<br />if (pos_do_i == -1 || pos_do_j == -1)<br />return false;<br />matrix[pos_do_i][pos_do_j] = cnt;<br />matrix[pos_do_j][pos_do_i] = cnt;<br />pos_pre.push_back(pos_do_i);<br />pos_pre.push_back(pos_do_j);<br />}<br />return true;<br />}<br />bool check_record_for_diff_weight(const vector<int>& cur,const vector<int>& use,const vector<bool>& b_larger)<br />{<br />for(int cnt=0;cnt<cur.size();cnt++)<br />{<br />if (cur[cnt] == use[cnt])<br />continue;<br />if (b_larger[cnt] == true)<br />{<br />if (cur[cnt]>use[cnt])<br />return true;<br />else<br />return false;<br />}<br />else<br />{<br />if (cur[cnt] < use[cnt])<br />return true;<br />else<br />return false;<br />}<br />}<br />return true;<br />}<br />double get_weight(int n_space,int n_dis)<br />{<br />if (n_dis != MAX_USE)<br />return n_space*n_space*n_space*n_dis*n_dis / (n*n);<br />else<br />return n_space*n_space*n_space;<br />}<br />int get_min_result()<br />{<br />int n_min = n+1;<br />for(int cnt=0;cnt<n;cnt++)<br />{<br />sort(matrix[cnt].begin(),matrix[cnt].end());<br />for(int cnt_cur=0;cnt_cur<n-1;cnt_cur++)<br />{<br />if (matrix[cnt][cnt_cur+1] - matrix[cnt][cnt_cur] < n_min)<br />n_min = matrix[cnt][cnt_cur+1] - matrix[cnt][cnt_cur];<br />}<br />}<br />return n_min;<br />}<br />void init_matrix()<br />{<br />matrix.clear();<br />matrix.resize(n);<br />for(int cnt_i=0;cnt_i<n;cnt_i++)<br />{<br />matrix[cnt_i].resize(n,0);<br />matrix[cnt_i][cnt_i] = MAX_USE;<br />}<br />}<br />public:<br />void display_matrix()<br />{<br />for(int cnt_i=0;cnt_i<n;cnt_i++)<br />{<br />for(int cnt_j=0;cnt_j<n;cnt_j++)<br />{<br />cout<<matrix[cnt_i][cnt_j]<<"/t";<br />}<br />cout<<endl;<br />}<br />}<br />int try_matrix_muti_times()<br />{<br />vector<vector<int>> matrix_bake_up;<br />int error = 0;<br />int n_times = 1;<br />init_matrix();<br />matrix_bake_up = matrix;<br />while(error != 3)<br />{<br />if (set_matrix(n_times) == false)<br />error++;<br />else<br />matrix_bake_up = matrix;<br />if (error == 0)<br />n_times = get_min_result();<br />else<br />n_times ++;<br />}<br />matrix = matrix_bake_up;<br />return get_min_result();<br />}<br />int try_matrix()<br />{<br />vector<vector<int>> matrix_bake_up;<br />int n_times = 1;<br />int n_re = 0;<br />init_matrix();<br />matrix_bake_up = matrix;<br />while(set_matrix(n_times))<br />{<br />n_re = get_min_result();<br />n_times = n_re;<br />matrix_bake_up = matrix;<br />}<br />matrix = matrix_bake_up;<br />return get_min_result();<br />}<br />class_last_one(int a_n):MAX_USE(a_n*a_n+100)<br />{<br />n = a_n;<br />}</p><p>};<br />int _tmain(int argc, _TCHAR* argv[])<br />{<br />for(int cnt=5;cnt<100;cnt++)<br />{<br />class_last_one lo(cnt);<br />cout<<cnt<<":"<<lo.try_matrix()<<endl;<br />}<br />return 0;<br />}<br />
結果如下:(5 到 49,result是結果,der_result_for_ideal_bound 是與理想上界的差,cpu_clock是消耗的cpu時鐘數)
5: result = 2 , der_result_for_ideal_bound = 0 , cpu_clock = 1
6: result = 2 , der_result_for_ideal_bound = 0 , cpu_clock = 10
7: result = 2 , der_result_for_ideal_bound = 1 , cpu_clock = 10
8: result = 2 , der_result_for_ideal_bound = 1 , cpu_clock = 10
9: result = 3 , der_result_for_ideal_bound = 1 , cpu_clock = 10
10: result = 3 , der_result_for_ideal_bound = 1 , cpu_clock = 20
11: result = 4 , der_result_for_ideal_bound = 1 , cpu_clock = 20
12: result = 4 , der_result_for_ideal_bound = 1 , cpu_clock = 20
13: result = 4 , der_result_for_ideal_bound = 2 , cpu_clock = 50
14: result = 5 , der_result_for_ideal_bound = 1 , cpu_clock = 40
15: result = 5 , der_result_for_ideal_bound = 2 , cpu_clock = 80
16: result = 5 , der_result_for_ideal_bound = 2 , cpu_clock = 120
17: result = 6 , der_result_for_ideal_bound = 2 , cpu_clock = 130
18: result = 6 , der_result_for_ideal_bound = 2 , cpu_clock = 210
19: result = 6 , der_result_for_ideal_bound = 3 , cpu_clock = 320
20: result = 7 , der_result_for_ideal_bound = 2 , cpu_clock = 260
21: result = 7 , der_result_for_ideal_bound = 3 , cpu_clock = 420
22: result = 7 , der_result_for_ideal_bound = 3 , cpu_clock = 580
23: result = 8 , der_result_for_ideal_bound = 3 , cpu_clock = 630
24: result = 8 , der_result_for_ideal_bound = 3 , cpu_clock = 660
25: result = 8 , der_result_for_ideal_bound = 4 , cpu_clock = 1270
26: result = 9 , der_result_for_ideal_bound = 3 , cpu_clock = 1070
27: result = 10 , der_result_for_ideal_bound = 3 , cpu_clock = 1040
28: result = 10 , der_result_for_ideal_bound = 3 , cpu_clock = 1350
29: result = 10 , der_result_for_ideal_bound = 4 , cpu_clock = 2120
30: result = 11 , der_result_for_ideal_bound = 3 , cpu_clock = 6260
31: result = 11 , der_result_for_ideal_bound = 4 , cpu_clock = 2700
32: result = 11 , der_result_for_ideal_bound = 4 , cpu_clock = 2950
33: result = 11 , der_result_for_ideal_bound = 5 , cpu_clock = 8080
34: result = 12 , der_result_for_ideal_bound = 4 , cpu_clock = 4310
35: result = 13 , der_result_for_ideal_bound = 4 , cpu_clock = 4110
36: result = 13 , der_result_for_ideal_bound = 4 , cpu_clock = 7970
37: result = 14 , der_result_for_ideal_bound = 4 , cpu_clock = 5230
38: result = 13 , der_result_for_ideal_bound = 5 , cpu_clock = 9520
39: result = 14 , der_result_for_ideal_bound = 5 , cpu_clock = 8910
40: result = 14 , der_result_for_ideal_bound = 5 , cpu_clock = 14410
41: result = 15 , der_result_for_ideal_bound = 5 , cpu_clock = 20310
42: result = 14 , der_result_for_ideal_bound = 6 , cpu_clock = 25880
43: result = 15 , der_result_for_ideal_bound = 6 , cpu_clock = 27760
44: result = 16 , der_result_for_ideal_bound = 5 , cpu_clock = 27790
45: result = 14 , der_result_for_ideal_bound = 8 , cpu_clock = 65320
46: result = 16 , der_result_for_ideal_bound = 6 , cpu_clock = 45770
47: result = 16 , der_result_for_ideal_bound = 7 , cpu_clock = 49920
48: result = 17 , der_result_for_ideal_bound = 6 , cpu_clock = 56730
49: result = 17 , der_result_for_ideal_bound = 7 , cpu_clock = 60300
total_clock:1004671