Hihocoder31 B Beautiful Sequence

 因为条件a[i-1] + a[i+1] ≥ 2 × a[i],可化简成a[i+1]-a[i]>=a[i]-a[i-1]

所以最后求的数列一定是先递减后不变后递增的

我们将数从小到大排序 (a[i]<a[i+1])

 考虑前i个数已经排完且符合条件,第i+1个数要符合条件只可能在最左端或最右端

考虑到只有60个数

从小到大向两侧加数,dp[i][j][k][l][p]表示最左,次左,次右,最右的数的大小,以及最后一个数在左侧还是右侧

其实可以把p这一维删掉,固定i为最大值,转移时满足可以将最右边换成最左边即可。

大概此时dp[i][j][k][l]表示一边最高为i次高为j 另一边最高为k次高为l的数量

#include<bits/stdc++.h>
using namespace std;
const long long mod=1000000007;
long long  n,i,i1,ans,ans1;
long long b[100],f[61][61][61][61];
int main()
{
	cin>>n;
	for (int i=1;i<=n;i++)	{cin>>b[i];}
    sort(b+1,b+1+n);
    ans=1;
    for (i=2;i<=n;i++)
    if (b[i]==b[i-1]) ans=ans*i%mod; else break;
    if (i==n+1)  cout<<ans<<endl;
    else
    { i1=i-1;
    //cout<<i1<<endl;
	  f[i1][i1][i1][i1]=1;
	  for (int i=i1;i<=n;i++)
	  for (int j=i1;j<=i;j++)
	  for (int k=i1;k<=i;k++)
	  for (int k1=i1;k1<=i;k1++)
	  {  //cout<<i+1<<' '<<j<<' '<<k<<' '<<k1<<' '<<f[i][j][k][k1]<<endl;
	     if (i==n) {ans1=(ans1+f[i][j][k][k1])%mod;  }
	    else
	    {
	    if (f[i][j][k][k1])
	    { // cout<<f[i][j][k][k1]<<endl;
	  	if (b[i+1]+b[j]>=b[i]*2) f[i+1][i][k][k1]=(f[i+1][i][k][k1]+f[i][j][k][k1])%mod;
	    //cout<<i+1<<' '<<i<<' '<<k<<' '<<k<<' '<<k1<<endl;
	    if (b[i+1]+b[k1]>=b[k]*2) f[i+1][k][i][j]=(f[i+1][k][i][j]+f[i][j][k][k1])%mod;
		}
	    }
	  } 
	  cout<<(ans1*ans)%mod<<endl;
	}
     
}

猜你喜欢

转载自blog.csdn.net/zzrh2018/article/details/81738407