码迷,mamicode.com
首页 > 其他好文 > 详细

解题报告:luogu P2401 不等数列

时间:2020-04-28 00:27:20      阅读:47      评论:0      收藏:0      [点我收藏+]

标签:define   lin   ret   www   报告   span   include   isp   line   

还是很菜,只能做绿题。
而且 whk 异常颓废,明天要给自己定任务了。。。
没带学读了
题目链接:P2401 不等数列
考虑 \(dp\)
如何继承呢?
我们来手玩一下吧,看 \(n=3\) 是的一种种 \(k=1\) 的情况:

\[3>1<2 \]

我们发现可以在四个位置插入 \(4\)
显然插到最前面不增加贡献,然而插到最后面一定产生贡献。
所以就不讨论了。
然后我们发现如果 \(4\) 插到 \(>\) 处就会成:\(<4>\)
显然产生一个贡献,然后看插到 \(<\) 处:\(<4>\)
没有贡献。
唉,怎么状态都一样啊一样啊
那么显然可以推出式子:
\(dp_{i,j}\) 为前 \(n\) 个数有 \(j\)\(<\) 时的方案数,那么:

\[dp_{i,j}=(j+1)dp_{i-1,j}+(i-j)dp_{i-1,j-1} \]

注意向两边放的情况,不要落下。
边界值很简单:

\[dp_{i,0}=1,dp_{i,{i-1}}=1 \]

当然还有特判一些无脑的点,比如 \(dp_{i,i}=0\)

\(Code\):

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

#define read(x) scanf("%d",&x)
#define MOD 2015

int dp[1005][1005];
int n,k;

int main()
{
	read(n),read(k);
	if(n==1){printf("0\n");return 0;}
	if(n==k){printf("0\n");return 0;}
	if(k==n-1){printf("1\n");return 0;}
	for(int i=2;i<=n;i++) dp[i][0]=dp[i][i-1]=1;
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=i-2;j++)
		{
			dp[i][j]=((j+1)*dp[i-1][j]%MOD+(i-j)*dp[i-1][j-1]%MOD)%MOD;
		}
	}
	printf("%d\n",dp[n][k]%MOD);
	return 0;
}

解题报告:luogu P2401 不等数列

标签:define   lin   ret   www   报告   span   include   isp   line   

原文地址:https://www.cnblogs.com/tlx-blog/p/12790938.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!