首页 > 技术文章 > 【arc071f】Infinite Sequence(动态规划)

cjyyb 2019-03-03 22:40 原文

【arc071f】Infinite Sequence(动态规划)

题面

atcoder
洛谷

题解

不难发现如果两个不为\(1\)的数连在一起,那么后面所有数都必须相等。
\(f[i]\)表示\([i,n]\)的填法数,初值\(f[n]=n,f[n-1]=n*n\)
考虑转移,
首先可以这里填上一个大于\(1\)的数然后后面连续若干个\(1\),这一部分的方案数是\(\sum_{j=i+3}^n f[j]\),这个后缀和记录一下就好了,然而还漏了一部分,即如果\(i+a_i>n\),那么这里的贡献的方案数就是\(1\),所以还需要补上\(i+1\)
第二种是在这一位填上连续两个大于\(1\)的数,方案数为\((n-1)^2\)
第三种是在这一位填上一个\(1\),方案数是\(f[i+1]\)

#include<cstdio>
#define MOD 1000000007
int n,f[1000010];
int main()
{
	scanf("%d",&n);f[n]=n;f[n-1]=1ll*n*n%MOD;
	for(int i=n-2,s=0;i>0;--i)s=(s+f[i+3])%MOD,f[i]=(f[i+1]+1ll*(n-1)*(n-1)+s+i+1)%MOD;
	printf("%d\n",f[1]);return 0;
}

推荐阅读