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
原文地址:https://www.cnblogs.com/keam37/p/4467776.html