【arc071f】Infinite Sequence(动态规划)

时间:2022-04-04 14:55:32

【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;
}