刷题——Ant Counting POJ - 3046
/*
给四个数:T,A,S,B表示,有A个数,数从1-T,现求集合元素个数为S-B的组合和,只用输出6位
假设给定4个数1,2,3,4每个数只有1个
0 1 2 3 4
0 1 0 0 0 0
1 1 1 0 0 0
2 1 1,2 12 0 0
3 1 1,2,3 12,13,23 123 0
4 1 1,2,3,4 12,13,23,14,24,34 123,124,134,234 1234
dp[i][j]表示前i个数组合成j长度的个数
很明显的可以看出,当长度小于等于第i个数的个数时dp[i][j]=dp[i][j-1]+dp[i-1][j]
大于时dp[i][j]=dp[i-1][j]+(dp[i][j-1]-dp[i-1][j-1-t_ni[i]])
大于时有冲突的部分要舍去,画表格和可以看出要舍去的部分时dp[i-1][j-1-t_ni[i]]带来的
dp[i-1][j]为前i-1个数组合成j长度的个数,对于同一个长度,这部分是垂直往下累加的
所以方程为:
dp[i][j]={
dp[i][j-1]+dp[i-1][j]:t_ni[i]<=j
dp[i-1][j]+(dp[i][j-1]-dp[i-1][j-1-t_ni[i]]
}
dp[i][j]=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1-t_ni[i]]+mod)%mod; 这里去掉冲突的部分会出现负数
我不是很清楚是在什么情况下出现的
*/
#include <stdio.h>
#include <string.h>
int t,a,s,b;
int t_ni[1010];
int dp[1010][100010];
const int mod=1000000;
int main(){
while(scanf("%d %d %d %d",&t,&a,&s,&b)!=EOF){
memset(t_ni,0,sizeof(t_ni));
int x;
for(int i=0;i<a;i++){
scanf("%d",&x);
t_ni[x]++;
}
for(int i=0;i<=t;i++){
dp[i][0]=1;
}
for(int i=1;i<=t;i++){
for(int j=1;j<=b;j++){
if(j<=t_ni[i]){
dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod;
}
else{
dp[i][j]=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1-t_ni[i]]+mod)%mod;
}
}
}
int num=0;
for(int i=s;i<=b;i++){
num=(num+dp[t][i])%mod;
}
printf("%d\n",num);
}
return 0;
}
给四个数:T,A,S,B表示,有A个数,数从1-T,现求集合元素个数为S-B的组合和,只用输出6位
假设给定4个数1,2,3,4每个数只有1个
0 1 2 3 4
0 1 0 0 0 0
1 1 1 0 0 0
2 1 1,2 12 0 0
3 1 1,2,3 12,13,23 123 0
4 1 1,2,3,4 12,13,23,14,24,34 123,124,134,234 1234
dp[i][j]表示前i个数组合成j长度的个数
很明显的可以看出,当长度小于等于第i个数的个数时dp[i][j]=dp[i][j-1]+dp[i-1][j]
大于时dp[i][j]=dp[i-1][j]+(dp[i][j-1]-dp[i-1][j-1-t_ni[i]])
大于时有冲突的部分要舍去,画表格和可以看出要舍去的部分时dp[i-1][j-1-t_ni[i]]带来的
dp[i-1][j]为前i-1个数组合成j长度的个数,对于同一个长度,这部分是垂直往下累加的
所以方程为:
dp[i][j]={
dp[i][j-1]+dp[i-1][j]:t_ni[i]<=j
dp[i-1][j]+(dp[i][j-1]-dp[i-1][j-1-t_ni[i]]
}
dp[i][j]=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1-t_ni[i]]+mod)%mod; 这里去掉冲突的部分会出现负数
我不是很清楚是在什么情况下出现的
*/
#include <stdio.h>
#include <string.h>
int t,a,s,b;
int t_ni[1010];
int dp[1010][100010];
const int mod=1000000;
int main(){
while(scanf("%d %d %d %d",&t,&a,&s,&b)!=EOF){
memset(t_ni,0,sizeof(t_ni));
int x;
for(int i=0;i<a;i++){
scanf("%d",&x);
t_ni[x]++;
}
for(int i=0;i<=t;i++){
dp[i][0]=1;
}
for(int i=1;i<=t;i++){
for(int j=1;j<=b;j++){
if(j<=t_ni[i]){
dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod;
}
else{
dp[i][j]=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1-t_ni[i]]+mod)%mod;
}
}
}
int num=0;
for(int i=s;i<=b;i++){
num=(num+dp[t][i])%mod;
}
printf("%d\n",num);
}
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.