运动员最佳分配问题(回溯)
题目:
这道题我的第一想法就是跟n皇后问题类似,所以实际在写的过程中我也使用了n皇后的模板,进行了简单的修改,即在判断位置的时候只要不是在同一行或同一列即可,无需要求不能在同一斜线上。最后利用记录下来的行列来进行运算该条路线的匹配度,对最大值进行更新即可。
我觉得计算匹配度这点是可以在进行路线匹配时可以同时更新计算的,但是我自己写的时候失败了,没有找到合适的方法。如果有大佬有想法,还请指教。
还有一个问题就是,这道题的要求是(1<=n<=20),但是我的程序执行下来基本上在十一二以后就会死掉,不是死循环吧,只是因为时间复杂度过高而导致的,我在网上也找了很多被人的代码进行运算尝试,但结果也拆不了多少,基本超过十多一点就死掉,不管是递归还是迭代。如果之后能够解决这个问题,我会重新更新,这里先记录一下吧。
因为是第一次发帖,不太会用,代码也是重新打了一遍因为没法复制粘贴所以不确定有没有错。因为我们老师要求要调用时间函数来分析时间复杂度,然后数据是随机生成的,还是取到了20,书上的案例是能过的。
这里是贴的代码:
#include<bits/stdc++.h>
using namespace std;
int x[21],o[21][21];
int maxn,n;
bool place(int k)
{
for(int i = 1; i < k; i ++)
if(x[k] == x[i])
return false;
return true;
}
void optimal()
{
x[1] = 0;
int t = 1;
int cmp = 0;
while(t > 0)
{
x[t]++;
while(x[t] <= n && !place(t))
x[t] ++;
if(x[t] <= n)
{
if(t == n)
{
cmp = 0;
for(int i = 1; i <= n; i ++)
cmp += o[i][x[i]];
if(maxn < cmp)
maxn = cmp;
}
else
x[++t] = 0;
}
else
t--;
}
}
int main()
{
ofstream in("input.txt");
ofstream out("output.txt");
srand(time(NULL));
int T = 20; //20组数据
while(T--)
{
n = rand()%20 + 1;
in << n << endl;
int p[n+1][n+1],q[n+1][n+1];
for(int i = 1; i <= n; i++)
{
for(int j = 1 ; j <= n; j ++)
{
p[i][j] = rand()%100 +1;
in << p[i][j] << " ";
}
in << endl;
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j++)
{
q[i][j] = rand()%100 + 1;
in << q[i][j] << " ";
}
in << endl;
}
in << endl;
clock_t start, end;
double duration;
start = clock(); //开始计时
if(n == 1)
{
cout << p[1][1]*q[1][1] << endl;
out << p[1][1]*q[1][1] << endl;
continue;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
o[i][j] = p[i][j] * q[i][j];//计算存储两人间的匹配度
maxn = 0;
memset(x, 0, sizeof(x));
optimal();
cout << maxn << endl;
out << maxn << endl;
end = clock();//结束计时
duration = (double)(end - start)/CLOCKS_PER_SEC;
cout << "TIME:" << duration << " seconds" << endl;
system("pause"); //暂停
}
return 0;
}