WHU 1579 Big data (DP)

题意:

      f[0]=0,f[i]=f[i-1]+a or b.

      求满足L<=∑f[n]<=R的序列的种数

      n<100.  |a|,|b|<=10000.  |L|,|R|<1e9

 


 

Solution

      其实就是一个背包问题.

      当a=b,序列 0 a a+a和 0 b b+b 竟然算不同的序列= =,巨坑

 

#include <iostream>

#define LL long long

using namespace std;

const int MOD = (int) 1e9 + 7;

const int M = 105;



LL N, a, b, L, R;

LL dp[109][109 * 109];



int main() {

    dp[0][0] = 1;

    for (int i = 1; i <= M; i++)

        for (int j = 0; j <= (i * (i - 1) / 2); j++) {

            dp[i][j] = (dp[i - 1][j] + dp[i][j]) % MOD;

            dp[i][j + i] = (dp[i - 1][j] + dp[i][j + i]) % MOD;

        }



    for (int i = 1; i <= M; i++)

        for (int j =  (i + 1) * i / 2 - 1; j >= 0; j--)

            dp[i][j] = (dp[i][j + 1] + dp[i][j]) % MOD;



    while (cin >> N >> a >> b >> L >> R) {

        if (a > b) swap (a, b);

        LL s = a * (1 + N) * N / 2;

        if (s <= R && b != a ) {

            LL nl = (L - s ) / (b - a), nr = (R - s) / (b - a) + 1;

            if ( (L - s) % (b - a) != 0) nl++;

            if (L - s <= 0) nl = 0;

            if (nl > (N + 1) *N / 2) nl = (N + 1) * N / 2  + 1;

            if (nr > (N + 1) *N / 2) nr = (N + 1) * N / 2 + 1;

            cout << (MOD + dp[N][nl] - dp[N][nr]) % MOD << endl;

        }

        else if (s >= L && s <= R && b == a) {

            LL ans = 1;

            for (int i = 1; i <= N; i++)

                ans = (ans * 2) % MOD;

            cout << ans << endl;

        }

        else

            cout << 0 << endl;

    }

    return 0;

}
View Code

 

你可能感兴趣的:(Data)