题意:有n(n<=13)座小岛,有个人要旅游全部的小岛,每个岛有权值,设当前走到的岛的权值为c,上个岛为b,上上个岛为a,那么ans+=c+c*b+a*b*c(如果当前岛和上上岛连通)
思路:
先枚举一下边界条件,然后就是正常的跑状态,一定要注意状态是从小跑到大的,所以我们此时的状态只能用到比自己的状态小的状态
n==1的时候要特判
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
typedef long long LL;
#define maxn 14
#define f(x) (x*1.0)
#define inf 0x3f3f3f3f
#define maxm maxn*maxn
#define lowbit(x) (x&(-x))
#define cheak(i) printf("%d ",i)
#define lson(x) (splay[x].son[0])
#define rson(x) (splay[x].son[1])
#define rfor(i,a,b) for(i=a;i<=b;++i)
#define lfor(i,a,b) for(i=a;i>=b;--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define mec(a,b) memcpy(a,b,sizeof(b))
int A[maxn];
bool Map[maxn][maxn];
LL dp[1<<maxn][maxn][maxn];
LL path[1<<maxn][maxn][maxn];
int main()
{
int n,m,i,j,k,T,u,v;
scanf("%d",&T);
while(T--)
{
mem(Map,false);
scanf("%d%d",&n,&m);
rfor(i,1,n) scanf("%d",&A[i]);
rfor(i,1,m)
{
scanf("%d%d",&u,&v);
Map[u][v]=Map[v][u]=true;
}
if(n==1)
{
printf("%d 1\n",A[1]);
continue;
}
mem(dp,-1);mem(path,0);
rfor(i,1,n)
rfor(j,1,n)
if(i!=j&&Map[i][j])//枚举边界状态
{
int state1=(1<<(i-1));
int state2=(1<<(j-1));
LL tmp=A[i]+A[j]+A[i]*A[j];
dp[state1+state2][i][j]=tmp;
path[state1+state2][i][j]=1;
}
int state;
rfor(state,0,(1<<(n))-1)
{
rfor(i,1,n)
{
if(state&(1<<(i-1)))
rfor(j,1,n)
{
if(state&(1<<(j-1))&&Map[i][j]&&i!=j)
rfor(k,1,n)
if(state&(1<<(k-1))&&Map[j][k]&&i!=k&&j!=k)
{
int state1=state-(1<<(i-1));
if(dp[state1][j][k]==-1) continue;
LL tmp=A[i]+A[i]*A[j]+dp[state1][j][k];
if(Map[i][k]) tmp+=A[i]*A[j]*A[k];
if(tmp>dp[state][i][j])
{
dp[state][i][j]=tmp;
path[state][i][j]=path[state1][j][k];
}
else if(tmp==dp[state][i][j])
path[state][i][j]+=path[state1][j][k];
}
}
}
}
state=(1<<(n))-1;
LL ans=-1,num=0;
rfor(i,1,n)
rfor(j,1,n)
{
if(dp[state][i][j]>ans)
{
ans=dp[state][i][j];
num=path[state][i][j];
}
else if(dp[state][i][j]==ans)
num+=path[state][i][j];
}
if(ans==-1) printf("0 0\n");
else printf("%lld %lld\n",ans,num/2);
}
return 0;
}