construct
题面:
题目描述
有一个长度为n的序列A,其中A[1]=1,A[n]=x,A[2…n-1]可以是1至k间任意一个正整数。求有多少个不同的序列,使得相邻两个数不同。
答案对10^9+7取模。
格式
输入共一行,包含三个数,n,k,x。
输出一个数,表示答案。
范围
这倒毒瘤题目,一眼望去就是数论啊!但我是真退不出来,结果这是道DP,呵呵,我遇上DP一般就是爆O的结果。
根据佳涵下午讲的,我打了半天才打出来,中间的分数浮动有点尴尬。
下面是zzp的表演时间:
f[i][0]表示第i个格子和1号点一样,f[1][1]表示第i个格子和第n个一样,f[i][2]表示不一样。
那么就可以很显然的得到方程了:f[i][1]=(f[i-1][0]),f[i][0]=(f[i-1][1]*(k-1)+f[i-1][0]*(k-2));
还有的就是初始值了,有点麻烦。。。
代码:
#include<bits/stdc++.h>
using namespace std;
int P=1e9+7;
int n,k,x;
long long f[100010][2];
int main()
{
freopen("construct.in","r",stdin);
freopen("construct.out","w",stdout);
scanf("%d %d %d",&n,&k,&x);
if(x==1) f[2][0]=k-1,f[2][1]=0;
else f[2][0]=k-2,f[2][1]=1;
for (int i=3;i<=n;i++)
{
f[i][1]=(f[i-1][0])%P;
f[i][0]=(f[i-1][1]*(k-1)+f[i-1][0]*(k-2))%P;
}
printf("%lld",(f[n-1][0])%P);
return 0;
}