• 波动数列(蓝桥杯)


    问题描述:


    观察如下数列:
    1 3 0 2 -1 1 -2 …
    这个数列中后一项总是比前一项增加 2 或者减少 3。
    栋栋对这种数列很好奇,他想知道长度为 n nn 和为 s ss 而且后一项总是比前一项增加 a aa 或者减少 b bb 的整数数列可能有多少种呢?

    输入格式
    输入的第一行包含四个整数 n   s   a   b n\ s\ a\ bn s a b,含义如前面说述。

    输出格式
    输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以 100000007 的余数。

    样例输入
    4 10 2 3

    样例输出
    2

    样例说明
    这两个数列分别是 {2 4 1 3} 和 {7 4 1 -2}。

    暴力解法(超时):

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. #define base 100000007
    6. int n,s,a,b;
    7. long long sum=0;
    8. void check(int k)
    9. {
    10. double change=s-k;
    11. double first=change/n;
    12. if(fmod(first,1)==0)
    13. {//计算出的第一个数为整数
    14. sum++;
    15. sum%=base;
    16. }
    17. }
    18. void calculate(int,int);
    19. int main()
    20. {
    21. cin>>n>>s>>a>>b;
    22. calculate(n-1,0);
    23. cout<
    24. return 0;
    25. }
    26. void calculate(int layer,int u)
    27. {//递归出口
    28. if(layer==0)
    29. {
    30. check(u);
    31. return;
    32. }
    33. int addition=layer*a;
    34. calculate(layer-1,u+addition);
    35. addition=(-b)*layer;
    36. calculate(layer-1,u+addition);
    37. }

    动态规划:

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. #define base 100000007
    6. long long a,b,n,s;
    7. const int N=1000010;
    8. int f[N]={0};
    9. //f[i][j]表示从(1~n-1)中前i个数中选择使得和为j的种类数
    10. //f[i][j]=f[i-1][j]+f[i-1][j-i]; f[i][0]=1;
    11. void create()
    12. {//参考01背包问题
    13. f[0]=1;
    14. for(int i=1;i<=n-1;i++)
    15. {
    16. int num=i*(i+1)/2;
    17. for(int j=num;j>=i;j--)
    18. {//需要倒序使得f[j-1]为f[i-1][j-1];
    19. f[j]=(f[j]+f[j-i])%base;
    20. }
    21. }
    22. }
    23. void calculate();
    24. int main()
    25. {
    26. cin>>n>>s>>a>>b;
    27. create();
    28. calculate();
    29. return 0;
    30. }
    31. void calculate()
    32. {
    33. int num=n*(n-1)/2;
    34. long long sum=0;
    35. for(int i=0;i<=num;i++)
    36. {
    37. long long u=i*a-(num-i)*b;
    38. long long temp=s-u;
    39. if(temp%n==0)
    40. {//n-1个位置取i个位置
    41. sum=(sum+f[i])%base;
    42. }
    43. }
    44. cout<
    45. }

  • 相关阅读:
    linux使用docker实现redis主从复制和哨兵模式
    virtualbox 扩展磁盘后在win10 虚拟机看不到新扩展的空间
    广州蓝景分享—「web前端素材」使用CSS动画效果(下)
    算法通关村第二关|白银|链表反转拓展【持续更新】
    JavaSE---逻辑控制
    netstat –ano|findstr “port”命令
    消息队列Kafka从入门到高级应用
    【已解决】PyCharm里的黄色波浪线
    怎么样把下载到的补丁集成到Win10 ISO镜像中?
    单元测试UnitTest
  • 原文地址:https://blog.csdn.net/Xm041206/article/details/136423683