波动数列 神奇的dp
1 3 0 2 -1 1 -2 ...
这个数列中后一项总是比前一项增加2或者减少3。
栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?
对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。
--------------------------------------------------------------------------------------------------------------------------
我算是摸透了,蓝桥杯最后两题如果数据大,肯定不是dfs,多半是DP
这个题是如何变出一个DP的递推公式呢,贼神奇
把a,b归结为一个状态p,第i个数要么是加a,要么是加b

对于n个数而言,a和b的总次数是
从1累加到(n-1)
我们暂且不论x是什么数,我们研究的是a出现的次数
对于第i个数来说 要么是a出现,要么是a不出现b出现,这两种状态

网上的思路大概是这样,dp[i-1][j]表示的是第i个数不取a
我想了很久,为什么dp[i-1][j-i]是表示第i个数取a,其他人对j有两种解释
1. dp(i,j)表示序列的前 i 项中 a 的次数为 j 时的方案种数。
2.dp[i][j],表示前i个元素组成和为j的序列的方案数,这里的和j表示的是所有的a的和.
但是j的范围是
我是这么理解的 i表示前i项,而j是a出现次数的和,不是a一共出现了多少次,而是从1累加到出现的次数。
比如对于前两项而言,a只能出现1次或者2次,那么j的最大值就是1+2 = 3
对于前三项而言,a只能出现1,2,3次,那么j的最大值就是1+2+3 = 6
我之前在这里想了好久好久,抱住萌萌的自己。
dp[0][0] = 1
dp[1][0] = dp[0][0] = 1 || dp[1][1] = dp[0][1]+dp[0][0] = 1
dp[2][0] = dp[1][0] = 1 || dp[2][1] = dp[1][1] =1 || dp[2][2] = dp[1][2] + dp[1][0] = 1 || dp[2][3] = dp[1][3] + dp[1][1] = 1
dp用滚动数组节省空间,最后判断x是不是整数。
#include<iostream>
using namespace std;
#define MOD 100000007
#define MAXN 1100
long long n,s,a,b;
long long all;
long long Bo[2][MAXN*MAXN];//作为滚动数组
int p=0;
//p为滚动数组标识,表示当前操作数组的第几行,(例如当前计算第i行,p指向操作Bo数组第0行,逻辑上i-1行是Bo数组第1行)
void fun_dp()
{
long long i,j;
//动态规划前初始化,只有一个体积为0的物品,可以装入容量为0的背包,容量大于0的背包方案数为0
Bo[p][0]=1;
for(i=1;i<n;i++)//有体积为1到n-1的n-1种物品
{
p=1-p;//p如果是0变换成1,如果是1变换成0
for(j=0;j<=i*(i+1)/2;j++)//背包容量从0到 i*(i-1)/2
{
if(i<j || i==j)
{
Bo[p][j] = (Bo[1-p][j] + Bo[1-p][j-i]) % MOD;
}else{
Bo[p][j] = Bo[1-p][j];
}
}
}
}
int fun_sum()
{
long long count=0,i;
long long temp;
for(i=0;i<=all;i++)
{
temp = s - i*a + (all - i)*b;
if(temp%n == 0)
{
count = (count+Bo[p][i])%MOD;
}
}
return count;
}
int main()
{
long long count;
cin >> n >> s >> a >> b;
all = n*(n-1)/2; //最多可以增加多少个a(背包容量最大值)
fun_dp();//进行动态规划的函数
count = fun_sum();//统计总数
cout << count;
return 0;
}
波动数列 神奇的dp的更多相关文章
- 0-1背包dp|波动数列|2014年蓝桥杯A组10-fishers
标题:波动数列 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. 栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a ...
- 转 蓝桥杯 历届试题 波动数列 [ dp ]
传送门 历届试题 波动数列 时间限制:1.0s 内存限制:256.0MB 锦囊1 锦囊2 锦囊3 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个 ...
- 算法笔记_172:历届试题 波动数列(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. 栋栋对这种数列很好奇,他想知道长度 ...
- 那些神奇的DP建模
(1). 迎接仪式 思路:性质,状态1拆为2,进行匹配 (2). 数字序列 思路:转换DP方程,玄学 (3). 序列分割 思路:性质,斜率优化 (4). 经营与开发 思路:倒序,秦久韶公式 (5). ...
- 蓝桥 PREV-30 历届试题 波动数列 【动态规划】
历届试题 波动数列 时间限制:1.0s 内存限制:256.0MB 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. ...
- Luogu P2467 [SDOI2010]地精部落 | 神奇的dp
题目链接 DP 题目大意:给定一个数n,求1~n这n个整数的所有排列中有多少个波动数列,将这个数量%p后输出. 什么是波动数列呢?顾名思义,就是一个大.一个小.一个大.一个小--或者是一个小.一个大. ...
- 蓝桥杯---波动数列(dp)(背包)(待解决)
问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. 栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减 ...
- tsinsen A1067. Fibonacci数列整除问题 dp
A1067. Fibonacci数列整除问题 时间限制:1.0s 内存限制:512.0MB 总提交次数:2796 AC次数:496 平均分:51.83 将本题分享到: 查看未格 ...
- [ZJOI2011]细胞——斐波那契数列+矩阵加速+dp
Description bzoj2323 Solution 题目看起来非常复杂. 本质不同的细胞这个条件显然太啰嗦, 是否有些可以挖掘的性质? 1.发现,只要第一次分裂不同,那么互相之间一定是不同的( ...
随机推荐
- Ubuntu搜狗输入法无法输入中文等问题
Linux版本的搜狗输入法经常崩溃,无法输入中文,今天作下记录,环境:Ubuntu14.04 64位 1.安装和卸载 Linux搜狗是基于框架fcitx的,先得安装框架Ubunt安装搜狗方法 也可以直 ...
- Windows/Linux下查看系统CPU使用最高的线程
参考:https://blog.csdn.net/qq_27818157/article/details/78688580 jstack -l 31372 > c:/31372.stack
- BFS练习-POJ.2386
Lake Counting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 35122 Accepted: 17437 Descr ...
- Java中堆、栈,静态方法和非静态方法的速度问题
一.堆和栈的速度性能分析 堆和栈是JVM内存模型中的2个重要组成部分,自己很早以前也总结过堆和栈的区别,基本都是从存储内容,存储空间大小,存储速度这几个方面来理解的,但是关于堆和栈的存储 ...
- pycharm界面美化,个人喜欢
进入file-setting选项 界面设置主要是在appearance和editor里面.appearance主要是整个pycharm的主题设置,比如文件管理窗口的颜色,其实就是软件本身的主题设置.我 ...
- Linux文件系统与目录结构
在Linux系统中,目录被组织成一个:单根倒置树结构,文件系统从根目录开始,用/来表示.文件名称区分大小写( 大小写敏感还需要看具体的文件系统格式 ),以.开头的为隐藏文件,路径用/来进行分割(win ...
- php图片压缩-高清晰度
php高清晰度无损压缩 经常会用到把上传的大图片压缩,特别是体积,在微信等APP应用上,也默认都是有压缩的,那么,怎么样对图片大幅度压缩却仍能保持较高的清晰度呢? 压缩通常是有按比例缩放,和指定宽度压 ...
- 虚拟机无法ping通物理机的解决方案
环境:Windows7下安装虚拟机,虚拟机上装有Ubuntu16.04的server版系统. 1.打开Windows防火墙,在打开或关闭Windows防火墙中 关闭Windows的防火墙. 2.禁用服 ...
- 解决VM-tools安装后,仍然无法与虚拟机复制
重新安装,不同是运行这个: vmware-install.real.pl 并执行 sudo apt-get install open-vm-tools-desktop 重启
- How to send CTRL+BREAK signal to detached command-line process
1.GenerateConsoleCtrlEvent function Sends a specified signal to a console process group that shares ...