前置芝士:next_permutation函数
next_permutation可以产生一个数组(vector)的下一个排列,具体使用方法为:
数组版:
next_permutation(a,a+n);
vector版:
next_permutation(a.begin(),a.end());
其作用是可以对一个已排序的数组(vector)做全排列,模板如下:
sort(a,a+n);
do
{
//内容
}while(next_permutation(a/*a.begin()*/,a+n/*a.end()*/);
注意:其返回值为bool类型。
进入正题
我们知道,第
2
i
−
1
2i-1
2i−1个人会和第
2
i
2i
2i个人聊天,而其产生的幸福值
应为
g
i
,
j
+
g
j
,
i
g_{i,j}+g_{j,i}
gi,j+gj,i,所以我们就可以得到方程为:
sum+=g[a[j]-1][a[j+1]-1];
sum+=g[a[j+1]-1][a[j]-1];
根据此公式,我们就可以得到一个循环嵌套,用来计算一个排列的总幸福值:
for(int i=0;i<n;i++)
{
for(int j=0;j<=n-i;j+=2)
{
if(j==n-1)continue;
sum+=g[a[j]-1][a[j+1]-1];
sum+=g[a[j+1]-1][a[j]-1];
}
a.erase(a.begin());
}
ans=max(ans,sum);
又由于这边要erase,我们需要将a数组拷贝成b数组:
vector<int> b;
for(int i=0;i<n;i++)
{
b.push_back(a[i]);
}
再加上next_permutation的模板和输入等,我们就可以得到完整代码(其他具体看注释)。
c u t e c o d e cute \; code cutecode:
#include<bits/stdc++.h>
#define n 5
using namespace std;
int g[8][8];
vector<int> a;
int main()
{
int ans=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>g[i][j];
}
a.push_back(i+1);//存入a数组
}//输入
do//当还有排列方法时,继续循环
{
int sum=0;
vector<int> b;
for(int i=0;i<n;i++)
{
b.push_back(a[i]);
}//把a拷贝到b
for(int i=0;i<n;i++)//每个人进去
{
for(int j=0;j<=n-i;j+=2)//求出这时的幸福值
{
if(j==n-1)continue;//如果这是个落单的人,跳过,不然会数组超限
sum+=g[b[j]-1][b[j+1]-1];//i和j聊天
sum+=g[b[j+1]-1][b[j]-1];//j和i聊天
}
b.erase(b.begin());//删除第一个人,即第一个人进去
}
ans=max(ans,sum);
}while(next_permutation(a.begin(),a.end())/*调用next_permutation函数产生下一个排列*/);
cout<<ans;
return 0;
}
注:千万不要抄题解哦!