Blue Bridge Cup - fluctuations sequences (dynamic programming + scroll array)

topic:

Here Insert Picture Description

input Output:

Here Insert Picture Description

Topic analysis:

First assume that the first number is x, then for adding or subtract a b-operation based on the number of x are behind on this manipulation will be P = {a, -b} expressed, and then the final necessarily :
x + ( x + P ) + ( x + 2 P ) + . . . + ( x + ( n 1 ) P ) = s x + (x+P) + (x+2P) + ... +(x+(n-1)P) = s
transformation of the above equation is about: n x + ( 1 + 2 + 3 + . . . + n 1 ) P = s nx + (1 + 2 + 3 + ... + n-1) p = p
by the above formula indicates the total number P is constant, as: n (n-1) /and since x is an integer, then
x = ( s n ( n 1 ) / 2 P ) / n x = (s - n(n-1)/2*P) / n

According to the above description, we can discuss a number of them, and a number in the range [0, n (n-1 ) / 2], dynamic programming can be used to analyze:
DP [I] [j] for the i-th elements expressed before and j is a number of programs, then the following situation:

  • When i is greater than j, i is the coefficient due i, so dp [i] [j] is necessarily from dp [i-1] [j] to the conversion, that is to say can not be used i
  • When i is less than or equal j, since j is greater than i, and i and can be used or not used, so there are the following conversion:
    DP [i] [j] = DP [i-. 1] [j] + DP [i-. 1 ] [ji]

According to the above rules, the range should be from 1 to i n-1, j is 0 to n (n-1) / 2, will take up too much memory, obviously, and then observe the above equation, the current state is only found in the previous state related, so you can use the scroll array resolved.

Code shows:

#include <iostream>
#include <cstring>
#include <cstdio>
#define MOD 100000007
using namespace std;

const int MAXN = 1005;
long long dp[2][MAXN*MAXN];
long long n,s,a,b;
int main()
{
    scanf("%lld%lld%lld%lld",&n,&s,&a,&b);
    dp[0][0] = 1;
    int flag = 0;
    for(int i=1;i<n;++i)
    {
        flag = 1 - flag;
        for(int j=0;j<=i*(i+1)/2;++j)
            if(j < i)
                dp[flag][j] = dp[1-flag][j];
            else
                dp[flag][j] = (dp[1-flag][j]%MOD + dp[1-flag][j-i]%MOD)%MOD;
    }
    long long ans,cnt = 0;
    for(int i=0;i<=n*(n-1)/2;++i)
    {
        ans = s - i*a + (n*(n-1)/2-i)*b;
        if(ans % n == 0)
            cnt = (cnt%MOD+dp[flag][i]%MOD)%MOD;
    }
    printf("%lld\n",cnt);
    return 0;
}

Published 61 original articles · won praise 7 · views 3626

Guess you like

Origin blog.csdn.net/weixin_42469716/article/details/104894326