Ant Counting(3046)

来源:互联网 发布:网络词背锅什么意思 编辑:程序博客网 时间:2024/05/29 10:52

大致题意:给n. m. l, y,n 种数,m个数, 问长度为 l 到 r 的序列有多少个

做法:d[i][j]表示从前i种选出j个的序列有多少个,dp[i][j] = sigma(dp[i-1][j-k]), k从0,到cont[i],因为数组太大,所以利用前缀和, 在加上滚动数组。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int mod = 1000000;const int M = 100100;int dp[2][M], n, m, l, r;int cont[M];int main(){int i, j;while(scanf("%d%d%d%d", &n, &m, &l, &r) == 4){memset(cont, 0, sizeof(cont));dp[0][0] = 1;int a;for(i = 1; i <= m; i++){scanf("%d", &a);cont[a] ++;}int nex, cur, sum;sum = cur = 0;nex = 1;for(i = 1; i <= n; i++){if(!cont[i])  continue;sum += cont[i];for(j = 0; j <= sum; j++){if(j)dp[cur][j] = (dp[cur][j] + dp[cur][j-1]) % mod;if(j-cont[i]-1 >= 0)dp[nex][j] = (dp[cur][j] + mod - dp[cur][j-cont[i]-1]) % mod;elsedp[nex][j] = dp[cur][j];}swap(cur, nex);}int ans = 0;for(i = l; i <= r; i++){ans = (ans + dp[cur][i]) % mod;}printf("%d\n", ans);}return 0;}

0 0
原创粉丝点击