zoukankan      html  css  js  c++  java
  • Java实现 蓝桥杯 历届试题 波动数列

    问题描述

    观察这个数列:
      1 3 0 2 -1 1 -2 …

    这个数列中后一项总是比前一项增加2或者减少3。

    栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?

    输入格式

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

    输出格式

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

    样例输入

    4 10 2 3

    样例输出

    2

    样例说明

    这两个数列分别是2 4 1 3和7 4 1 -2。

    数据规模和约定

    对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5;
      对于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。

    import java.util.Scanner;
    
    public class Main {
        public static long n, s, a, b;
        public static long result = 0L;
        public static int e = 0;
        public static long[][] dp;;
        
        public void getDP() {
        //DP[1-e][j]这里的意思是,我的+j个a,
        //一直1-e就是是上一个
            dp = new long[2][1000005];
            dp[e][0] = 1;
            for(int i = 1;i < n;i++) {
                e = 1 -e;
                for(int j = 0;j <= i * (i + 1) / 2;j++) {
                    if(i > j)
                        dp[e][j] = dp[1 - e][j];
                    else
                    //这个意思是,我可以是上次的+j个a,也可以是在-i个b,这里就变成了+j-i个a
                    //因为我只有两种选择,一个是+a一个是-b,我是j-i个+a,剩下的就是i个-b
                        dp[e][j] = (dp[1 - e][j] + dp[1 - e][j - i]) % 100000007;
                }
            }
        }
        
        
        public static void main(String[] args) {
            Main test = new Main();
            Scanner in = new Scanner(System.in);
            n = in.nextLong();
            s = in.nextLong();
            a = in.nextLong();
            b = in.nextLong();
            test.getDP();
            for(long i = 0;i <= n * (n - 1) / 2;i++) {
                long t = s - i * a + (n*(n-1)/2-i) * b;//t就是除去添加a和删去b剩下的数的和,必须被n整除才可以
                //这里你要是问为什么上句话是必须被n整除,你可以出门右转了
                //因为我只有两种操作,我把两种操作的数字都删了,就是剩下的数字的和了,我剩下数字的和是我n个数平分的
                if(t % n == 0)//哪种方式合适就用哪种
                    result = (result + dp[e][(int) i]) % 100000007;
            }
            System.out.println(result);
        }
    }
    
  • 相关阅读:
    POJ3159 Candies —— 差分约束 spfa
    POJ1511 Invitation Cards —— 最短路spfa
    POJ1860 Currency Exchange —— spfa求正环
    POJ3259 Wormholes —— spfa求负环
    POJ3660 Cow Contest —— Floyd 传递闭包
    POJ3268 Silver Cow Party —— 最短路
    POJ1797 Heavy Transportation —— 最短路变形
    POJ2253 Frogger —— 最短路变形
    POJ1759 Garland —— 二分
    POJ3685 Matrix —— 二分
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13077983.html
Copyright © 2011-2022 走看看