构造序列——宇&周周小猪

一道涉及数论和动态规划的题目,要求在序列A中,已知A[1]=1, A[n]=x,且中间元素在1到k之间,计算不同序列的数量。题目描述和解题思路,包括动态规划状态转移方程的设定。" 45102191,5006401,Android水平ListView实现:HorizontalListView详解,"['Android开发', '前端开发', 'ListView', '自定义组件']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值