第五届蓝桥杯C/C++本科A组初赛波动数列解题报告
来源:互联网 发布:软件质量分析师 编辑:程序博客网 时间:2024/04/30 06:20
原题可化为nx+(n-1)p(1)+(n-2)p(2)+…+p(n)=s,其中n为数列长度,x为初值,p(i)={a,-b}。本题的目标是给出不同的p序列,使得等式成立并且x为整数。自然而然可以想到枚举的方法,给出不同的序列,令t=s-Σi*p(n-i),若t%n==0则是一种可取的方案。直接枚举肯定会超时,所以需要进一步考虑。注意到,a和b的总数为n(n-1)/2个(所有p前系数的和),所以我们只需要枚举a的个数,将t修改为t=s-ca-(n(n-1)/2-c)b,c为枚举数,0<=c<=n(n-1)/2。
当然满足条件的c的个数并不是我们想要的,因为给定一个c,存在多种组合方式。但是可以发现,每个c都是由1~n-1中若干元素组成的。于是问题转化为求容量为c的01背包的方案数。对于本题,可以写为:(f[i][j]为前i个物体构成j体积的方案数,第i个物体的体积为i)
f[i][j]=f[i-1][j], i>j
f[i-1][j]+f[i-1][j-i], j>=i
注意到递推式只和前一状态有关,故可以使用滚动数组;根据定义,可以预先算出每一个f[n][i],避免重复计算;前i个货物最多只能达到i*(i+1)/2的体积,所以大于这个数值的部分没有必要计算。具体的请看代码,其实就这么几行。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#define MAXN 1100#define MOD 100000007using namespace std;int F[2][MAXN*MAXN];int e = 0;long long n,s,a,b;int cnt = 0;void calc(int elem){ int i,j; memset(F,0,sizeof(F)); F[e][0]=1; for(i=1;i<n;i++) { e=1-e; for(j=0;j<=i*(i+1)/2;j++) { if(i>j) F[e][j]=F[1-e][j]; else F[e][j]=(F[1-e][j]+F[1-e][j-i])%MOD; } }}int main(){ scanf("%I64d%I64d%I64d%I64d",&n,&s,&a,&b); long long i,t; calc(n*(n-1)/2); for(i=0; i<=n*(n-1)/2; i++) { t = s - i*a + (n*(n-1)/2-i)*b; if(t%n==0) cnt = (cnt+F[e][i])%MOD; } printf("%d",cnt); return 0;}
0 0
- 第五届蓝桥杯C/C++本科A组初赛波动数列解题报告
- 2014 第五届蓝桥杯预赛c/c++本科B组 解题报告
- 第五届蓝桥杯软件大赛C/C++本科B组解题报告
- 第五届蓝桥杯软件大赛C/C++本科B组决赛解题报告
- 波动数列 解题报告
- 第二届蓝桥杯C++本科B组初赛解题报告
- 第六届蓝桥杯2015本科B组c/++部分解题报告
- 2014年第五届蓝桥杯预赛 C/C++本科B组 快速解题思路及报告(完整版,4.9修订)
- 第五届蓝桥杯A组java—波动数列
- 2014年蓝桥杯预赛 C/C++本科A组 解题报告 史丰收速算
- 2013蓝桥杯预赛C/C++本科B组解题报告
- 第四届蓝桥杯c\c++本科B组初赛 错误票据
- 2014第五届蓝桥杯国赛决赛c/c++本科B组试题总结及解题答案
- 2014届第五届蓝桥杯 C语言本科B组试题
- 第五届蓝桥杯预赛 本科C/C++ B组 蚂蚁感冒
- 2014第五届蓝桥杯C/C++程序设计本科B组决赛
- 2014年蓝桥杯预赛 C/C++本科B组 解题报告 史丰收速算
- 2014年蓝桥杯预赛 C/C++本科B组 解题报告 打印图形
- 玩家离开手游的5大原因 前60秒最重要
- php 正则表达式匹配中文
- 第三章实验作业2
- NoSql学习之路一redis做消息队列
- 【索引】Designing Efficient Algorithms:Examples:Intermediate
- 第五届蓝桥杯C/C++本科A组初赛波动数列解题报告
- 积少成多,汇沙成塔!
- Sqrt(x)
- hdu 1160 - FatMouse's Speed
- 在html的<img src="">中调用js的函数或者js变量来指定图片路径
- Climbing Stairs
- github
- week1
- 深入分析MapReduce执行原理