hihoCoder 1596 : Beautiful Sequence
Description
Consider a positive integer sequence a[1], ..., a[n] (n ≥ 3). If for every 2 ≤ i ≤ n-1, a[i-1] + a[i+1] ≥ 2 × a[i] holds, then we say this sequence is beautiful.
Now you have a positive integer sequence b[1], ..., b[n]. Please calculate the probability P that the resulting sequence is beautiful after uniformly random shuffling sequence b.
You're only required to output (P × (n!)) mod 1000000007. (Obviously P × (n!) is an integer)
Input
First line contains an integer n. (3 ≤ n ≤ 60)
Following n lines contain integers b[1], b[2], ..., b[n]. (1 ≤ b[i] ≤ 1000000000)
Output
Output (P × (n!)) mod 1000000007.
Sample Input
4 1 2 1 3
Sample Output
8
https://hihocoder.com/problemset/problem/1596
dp鬼题
题目条件可化为a[i+1]-a[i]>=a[i]-a[i-1]
考虑排序再做分配
根据分析我们发现最后的高度序列是一个勾函数,先减小后增大
我们讨论b[i-1],b[i],b[i+1]的情况
显然i-1和i+1不可能同时大于i
只可能一个大于i一个小于,或两个都大于
但是两个都大于的情况显然只有一次,两边是不会有的
如5 3 5 1 3 5
那么就出现了两个都小于的情况
那么我们就可以dp
令f[i][j][k][l]表示最左边两个为i,j 最右边两个为k,l
我们先将最小值放入f[1][0][1][0]=1
接下来要放的数为max(i,k)+1,为什么?因为是排过序的,从小到大放就行了
判断是否满足:a[i+1]-a[i]>=a[i]-a[i-1]
还有一个细节:
当有多个最小值时,显然不能直接dp,以最小值数量为l=3举例
因为直接dp只能得到4种,而实际有6种(此题鬼处)
所以把所有最小值缩为一个,最后乘l!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 int Mod=1000000007; 8 long long f[61][61][61][61],a[61],p[61],tmp,ans; 9 int n; 10 int main() 11 {int i,j,k,l=0; 12 cin>>n; 13 for (i=1;i<=n;i++) 14 { 15 scanf("%lld",&a[i]); 16 } 17 sort(a+1,a+n+1); 18 p[0]=1; 19 for (i=1;i<=n;i++) 20 p[i]=(p[i-1]*i)%Mod; 21 for (i=1;i<=n;i++) 22 if (a[i]==a[1]) l++; 23 tmp=p[l]; 24 for (i=2;i<=n-l+1;i++) 25 a[i]=a[i+l-1]; 26 n=n-l+1; 27 f[1][0][1][0]=1; 28 for (i=1;i<=n;i++) 29 { 30 for (j=0;j<=n-1;j++) 31 { 32 for (k=1;k<=n;k++) 33 { 34 for (l=0;l<=n-1;l++) 35 { 36 int z=max(i,k)+1; 37 if (z==n+1) 38 { 39 ans+=f[i][j][k][l]; 40 ans%=Mod; 41 continue; 42 } 43 if (a[z]-a[k]>=a[k]-a[l]||l==0) 44 f[i][j][z][k]+=f[i][j][k][l],f[i][j][z][k]%=Mod; 45 if (a[z]-a[i]>=a[i]-a[j]||j==0) 46 f[z][i][k][l]+=f[i][j][k][l],f[z][i][k][l]%=Mod; 47 } 48 } 49 } 50 } 51 cout<<(ans*tmp)%Mod; 52 }