首页 > 其他分享 >波动数列

波动数列

时间:2024-03-16 20:45:59浏览次数:14  
标签:ch 数列 text 波动 split equiv dp mod

一、题目描述

P8614 [蓝桥杯 2014 省 A] 波动数列

二、问题简析

设第一个数为 \(x_0\),\(d_i=a~or~-b\),则长度为 \(n\) 的数列的和为:

\[\begin{split} s&=x_0+x_1+x_2+...+x_{n-1}\\ &=(x_0 + 0) + (x_0+d_1) + (x_0+d_1+d_2)+...+(x_0+d_1+...+d_{n-1})\\ &=n*x_0+0+(n-1)*d_1+(n-2)*d_2+...+d_{n-1} \end{split} \]

令 \(z_{i}=0+(n-1)*d_1+(n-2)*d_2+...+(n-i)*d_i\),则 \(s=n*x_0+z_{n-1}\)。

\[\begin{split} &\because s = n * x_0 + z_{n-1} \\ &\therefore x_0=\frac{s-z_{n-1}}{n} \in \mathbb{Z} \\ &\therefore s-z_{n-1} \equiv 0~(\text{mod}~n) \\ &即 s \equiv z_{n-1}~(\text{mod}~n) \end{split} \]

设 \(dp[i][j]=\) 使 \(j\equiv z_i(\text{mod}~n)\) 的方案数,则

\[\begin{split} z_i&=z_{i-1}+(n-i)*d_i\\ z_{i-1}&=z_i-(n-i)*d_i\\ z_{i-1} &\equiv z_i-(n-i)*d_i~(\text{mod}~n) \end{split} \]

\(d_i\) 可能的值为 \(a\) 或 \(-b\),

\[z_{i-1}\equiv \begin{cases} z_i-(n-i)*a\\ z_i+(n-i)*b \end{cases} ~(\text{mod}~n) \]

至此,我们可以写出递归方程

\[\begin{split} dp[i][j~(\text{mod}~n)] &= dp[i][z_i~(\text{mod}~n)] \\ &=dp[i-1][z_{i-1}~(\text{mod}~n)]~//~包含两种情况\\ &=dp[i-1][z_i-(n-i)*a~(\text{mod}~n)]+dp[i-1][z_i+(n-i)*b~(\text{mod}~n)] \end{split} \]

注:

  • 1、取模运算可能会产生负数,而数组肯定不能通过负数访问,所以要转化成正数:(x % n + n) % n
  • 2、dp[0][0]=1:因为 \(z_0=0\),算一种情况。

三、AC代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int quickin(void)
{
	int ret = 0;
	bool flag = false;
	char ch = getchar();
	while (ch < '0' || ch > '9')
	{
		if (ch == '-')    flag = true;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9' && ch != EOF)
	{
		ret = ret * 10 + ch - '0';
		ch = getchar();
	}
	if (flag)    ret = -ret;
	return ret;
}

const int MOD = 1e8 + 7;
ll n, s, a, b, dp[1003][1003];

int get_mod(ll x)
{
	return (x % n + n) % n; 
} 

int main()
{
	#ifdef LOCAL
	freopen("test.in", "r", stdin);
	#endif
	
	cin >> n >> s >> a >> b;
	dp[0][0] = 1;
	for (int i = 1; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			dp[i][j] = (dp[i - 1][get_mod(j - (n - i) * a)] + dp[i - 1][get_mod(j + (n - i) * b)]) % MOD;
		}
	}
	
	cout << dp[n - 1][get_mod(s)] << endl;
	
	return 0;
}

标签:ch,数列,text,波动,split,equiv,dp,mod
From: https://www.cnblogs.com/hoyd/p/18077554

相关文章

  • 详细解释可变参数列表C语言
    目录考研复习-函数栈帧(详解)一.什么是可变参数列表?1.1 求两个数据中的最大值1.2求多个数据中的最大值1.3逐步分析 1.va_start 2.va_arg3.va_end 4._INTSIZEOF(t)第一步理解:4的倍数第二步理解:最小4字节对齐数                第三步理解:理解源代......
  • (斐波那契数列),假如兔子都不死,问到第12个月时一共有多少只兔子 //(有一对兔子,从出生后第
    //斐波那契数列,计算兔子的数量:11235813......从第三个数开始,//后一个数都是前两个数的和,假如兔子都不死,问到第12个月时一共有多少只兔子//(有一对兔子,从出生后第三个月开始,每一个月生一对兔子,小兔子同理)publicclassRabitDemo1{//斐波那契数列,计算兔子的数量:1......
  • 有趣的数列
    一个比较正常,自然的思路:看这篇题解像这种全排列的问题,一个很正常的想法就是从小到大进行依次放置,再看一下每次放置的限制是什么我自己想的时候,是直接先把所有奇数位的数字取出来,那么显然取了\(n\)个数,剩下的\(n\)个数肯定是偶数位的,而且由题意,他们只存在唯一的一种摆法(即从小到......
  • 数学分析复习:数列和级数收敛
    数学分析复习:数列和级数收敛1.实数列收敛的定义2.实数项级数收敛的定义3.单调有界实数列必收敛4.Bolzano-Weierstrass定理5.Cauchy列5.1Cauchy列的性质5.2实数列的Cauchy收敛准则5.3实数项级数的Cauchy收敛准则6.Euler常数e的构造7.判断实数列和实数项级数收......
  • 【VINKA原厂技术支持】电源供电系列高稳定性抗电压波动 6按键/通道触摸触控芯片VK3606
    概述 VK3606D具有6个触摸按键,可用来检测外部触摸按键上人手的触摸动作。该芯片具有较高的集成度,仅需极少的外部组件便可实现触摸按键的检测。提供了6路1对1直接输出低电平有效。最长输出时间10S。芯片内部采用特殊的集成电路,具有高电源电压抑制比,可减少按键检测错误的发生,此特......
  • abc234E 不小于X的数位构成等差数列的最小数字
    给定X,求不小于X的整数,满足各个数位正好构成等差数列。1<=X<=1E17直接枚举首项和公差,找出所有可行的解,取最优值即可。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#definerep(i,a,b)for(inti=a;i<=b;i++)#defineper(i,a,b)for(inti=b;i>=a;......
  • 线段树维护区间等差数列
    线段树维护区间等差数列我们采用用两个懒标记分别维护等差数列首项k和公差d维护时有个细节是假如我有左右两个区间需要合并信息时我们对于左边还是k和d但是对于右边信息此时k应该变成k+len*d,公差还是dlen表示的是右边区间长度牛牛的等差数列#include......
  • [蓝桥杯 2019 省 B] 等差数列
    实际上这道题不需要先排序再求gcd,因为无论是哪两项之前作差,都不会影响最后的gcd的结果。因为公差是从a2-a1开始算的,因此i=1时要特殊处理,不能把a1-0计入贡献,否则会算出错误的gcd。即作差时不要加上a1-0,统计最值时不要漏掉a1#include<iostream>#include<stdio.h>#include<a......
  • 无聊的数列[题解]
    无聊的数列[link1][link2]题目大意给定一个数列\(A\)有两种操作:将数列中\(A_i\)(\(L\leqi\leqR\))加上一个等差数列(首项D公差K)查询数列中第P位数区间加上一个等差数列可以用差分来解决例原序列:000000差分序列:000000等差序列:13579(首项1......
  • R语言有状态依赖强度的非线性、多变量跳跃扩散过程模型似然推断分析股票价格波动
    原文链接:http://tecdat.cn/?p=23010 原文出处:拓端数据部落公众号跳跃扩散过程为连续演化过程中的偏差提供了一种建模手段。但是,跳跃扩散过程的微积分使其难以分析非线性模型。本文开发了一种方法,用于逼近具有依赖性或随机强度的多变量跳跃扩散的转移密度。通过推导支配过程时变......