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