思路:
设f[i][j]表示状态为i,最后一个到j时的最大周长
记录方案时就再开一个数组做同样处理就行
c o d e code code
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long n, ans, ans1;
long long a[1001];
long long f[20][100000], an[20][100000];
long long num[1001000];
int main()
{
scanf("%lld", &n);
num[0]=1;
for(long long i=1; i<=n; i++)
{
scanf("%lld", &a[i]);
num[i]=num[i-1]*2;
f[i][num[i-1]]=a[i]*2;
an[i][num[i-1]]=1;
}
for(long long s=1; s<=num[n]-1; s++)
{
for(long long i=1; i<=n; i++)
{
if((s&num[i-1])==0)
continue;
for(long long j=1; j<=n; j++)
{
if((s&num[j-1])!=0)
continue;
long long t=s+num[j-1];
long long len;
if(a[j]>a[i])
len=a[j]*2-a[i]*2;
else
len=0;
if(f[j][t]<f[i][s]+len)
{
f[j][t]=f[i][s]+len;
an[j][t]=an[i][s];
}
else if(f[j][t]==f[i][s]+len)
an[j][t]+=an[i][s];
}
}
}
long long ans=0, ans1=0;
for(long long i=1; i<=n; i++)
{
if(ans<f[i][num[n]-1]+n*2)
ans=f[i][num[n]-1]+n*2, ans1=an[i][num[n]-1];
else if(ans==f[i][num[n]-1]+n*2)
ans1+=an[i][num[n]-1];
}
printf("%lld %lld", ans, ans1);
return 0;
}