您的位置:首页 > 产品设计 > UI/UE

AtCoder Regular Contest 071 F - Infinite Sequence 动态规划

2017-11-04 12:36 447 查看

题意

问有多少个无限长度的数组要满足以下条件

1. 数组仅包含1, 2, 3, …, n

2. 如果n <= i, j,那么ai = aj

3. 如果i < j < k <= i + ai,那么aj = ak

答案对1e9 + 7 取模

1 <= n <= 10^6

分析

根据第二个条件可以得出这其实就是一个长度为n的数组。。。

接着分析一下第三个条件的性质:

如果a[i] > 1,且a[i+1] > 1,那么a[i+1…n]均等于a[i+1]。若a[i+1]=1,则a[i+1…i+a[i]]=1。

考虑dp,设f[i]表示一个长度为i的数组,且第i+1位可以任意放的方案。

分析一下不难发现f[i]=(∑i−1j=1f[j])−f[i−2]。也就是枚举i前面第一个k满足a[k] > 1的位置。

ans=f[n]+f[n−1]∗(n−1)+∑n−2i=0f[i]∗((n−1)∗(n−1)+i+1)

也就是枚举最后一个k满足a[k+1…n]都已经被确定。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

const int N=1000005;
const int MOD=1000000007;

int n,f
,s
;

int main()
{
scanf("%d",&n);
f[1]=f[2]=f[0]=s[0]=1;s[1]=2;s[2]=3;
for (int i=3;i<=n;i++)
{
f[i]=f[i-1]+s[i-3];
f[i]-=f[i]>=MOD?MOD:0;
s[i]=s[i-1]+f[i];
s[i]-=s[i]>=MOD?MOD:0;
}
int ans=f
;
ans+=(LL)f[n-1]*(n-1)%MOD;
ans-=ans>=MOD?MOD:0;
for (int i=0;i<=n-2;i++) ans+=(LL)f[i]*((LL)(n-1)*(n-1)%MOD+i+1)%MOD,ans-=ans>=MOD?MOD:0;
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: