UVa 10616

state:
    dp[i][j][k] - how many ways to select j numbers from i numbers, and with remainder k when the sum of those j numbers divides d

transition:
    dp[i][j][k]=dp[i-1][j][k]+dp[i-1][j-1][K], K equals the remainder before we select number j

this dp transition looks just like the one used to generate combination table:
    dp[i][j]=dp[i-1][j-1]+dp[i-1][j]
which also can generate the famous pascal's triangle...
/* UVas */
/*****************************************************************************/
#define N 201
#define M 21
int n, q, d, m, t=1;
int p[N];
unsigned long long D[N][M][M];
int main(void) {
    while (scanf("%d %d\n", &n, &q)>0&&n&&q) {
        for (int i=1; i<=n; i++)
            scanf("%d", &p[i]);
        printf("SET %d:\n", t++);
        for (int i=1; i<=q; i++) {
            scanf("%d %d", &d, &m);
            printf("QUERY %d: ", i);
            memset(D, 0, sizeof(D));
            for (int i=0; i<=n; i++)
                D[i][0][0]=1;
            for (int i=1; i<=n; i++)
                for (int j=1; j<=m; j++)
                    for (int k=0; k<d; k++) {
                        int r=(k-p[i]%d)%d;
                        D[i][j][k]=D[i-1][j][k]+D[i-1][j-1][r>=0?r:r+d];
                    }
            printf("%lld\n", D[n][m][0]);
        }
    }
}
/*****************************************************************************/

No comments :

Post a Comment