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; }
相关文章推荐
- AtCoder Regular Contest 074 E - RGB Sequence 动态规划
- AtCoder Regular Contest 081 F - Flip and Rectangles 动态规划
- AtCoder Regular Contest 071
- AtCoder Regular Contest 066 E - Addition and Subtraction Hard 动态规划
- AtCoder Regular Contest 068 F - Solitaire 动态规划
- AtCoder Regular Contest 065 Shuffling 动态规划
- AtCoder Regular Contest 071 F
- Atcoder regular Contest 073(C - Sentou)
- AtCoder Regular Contest 085 C题题解
- AtCoder Regular Contest 086
- AtCoder Regular Contest 088
- AtCoder Regular Contest 077
- AtCoder Regular Contest 089 D Checker
- AtCoder Regular Contest 076 F - Exhausted? 霍尔定理+线段树
- AtCoder Regular Contest 077 E - guruguru 二阶差分
- AtCoder Regular Contest 079-C - Cat Snuke and a Voyage
- Atcoder AtCoder Regular Contest 079 E - Decrease (Judge ver.)
- AtCoder Regular Contest D - Remainder Reminder 取余问题
- Atcoder Regular Contest 092 A 的改编
- AtCoder Regular Contest 093 D - Grid Components