2018.5.19 T2

漂亮
【问题描述】
小美今天对于数列很有兴趣。
小美打算找出一些漂亮的序列。
一个漂亮的序列的限制如下:
1. 长度为 n ,而且数列里只包含 [1,n] 的整数。
2. 要不是不降的序列就是不升的序列。
小美想知道有多少个合法的序列满足要求。
【输入格式】
从文件 pretty.in 中读入数据。
第一行一个正整数 n 表示数列的大小。
【输出格式】
输出到文件 pretty.out 中。
第一行输出一个数字表示答案。由于这个数字会很大,你需要输出他
模 1000000007。
【样例输入】
2
【样例输出】

4

-------------------------------------------------------------------

50% 显然是一个dp,先求不降序,ans=不降序*2-n;

f[i][j]表示第i位,数字为j的方案数,暴力一点的话,f[i][j]=sigma(f[i+1][k]|k>=j)

这是O(n^3) ,想想如何优化,然后可以发现 f[i][j]=f[i][j-1]-f[i+1][j-1](可以画图理解),此时已是O(n^2)

然后将f数组输出一下,发现了神奇的东西

6 3 1
3 2 1
1 1 1 // n==3

这不是杨辉三角吗!

ans=sigma(C(i,n+i-1)| 0<i<n)=>(2*n-1)!/n!*(n-1)!

除法需要求逆元,直接费马小定理

#include <cstdio>//50%
#include <cstring>
using namespace std;
const int P=1000000007;
int n,ans;
int f[4005][4005];
int dfs(int x,int id) {
	if (f[x][id]!=-1) return f[x][id];
	f[x][id]=0;
	if (x==n) f[x][id]=1;
	else if (id==1) {
		for (int i=id;i<=n;i++) {
			f[x][id]=(f[x][id]+dfs(x+1,i))%P;
		}
	}
	else f[x][id]=(f[x][id-1]-f[x+1][id-1]+P)%P;
	return f[x][id];
}
int main() {
	freopen("pretty.in","r",stdin);
	freopen("pretty.out","w",stdout);
	memset(f,-1,sizeof f);
	scanf("%d",&n);
	for (int i=1;i<=n;i++) ans=(ans+dfs(1,i))%P;
	ans=((ans-n)*2%P+n)%P;
	printf("%d",ans);
}

#include <cstdio>
#include <cstring>
using namespace std;
#define int long long
const int P=1000000007;
int n,ans=1;
int bin[200007]={1};
int ksm(int a,int b,int p) {
	int s=1;
	for (;b;a=(a*a)%P,b>>=1) if (b&1) s=s*a%P;
	return s;
}
int C(int m,int n) {
	int k=bin[m]*bin[n-m]%P;
	return bin[n]*ksm(k,P-2,P)%P;
}
signed main() {
	freopen("pretty.in","r",stdin);
	freopen("pretty.out","w",stdout);
	scanf("%lld",&n);
	for (int i=1;i<=n*2;i++)
		bin[i]=(bin[i-1]*i)%P;
	for (int i=1;i<n;i++)
		ans=(ans+C(i,n+i-1))%P;
	ans=(ans*2-n+P)%P;
	printf("%lld",ans);
}


猜你喜欢

转载自blog.csdn.net/qq_41893580/article/details/80382188
T2