LightOJ1191 Bar Codes(DP)
题目大概是,二进制数可以看作是由几段连续的0和连续的1组成,问:n位没有前导0的 且 共用k段连续0/1组成的 且 连续0/1个数不超过m的二进制数有多少个。
- 用dp[n][k][m]表示问题
- dp[i][1][j]=1 (i<=j)
- 通过枚举第一段连续数字的个数first,使dp[n][k][m]从dp[n-first][k-1][m]转移,具体就是dp[n][k][m]=∑dp[n-i][k-1][m] (1<=i<=m)
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 long long d[51][51][51]; 5 int main(){ 6 for(int i=1; i<=50; ++i){ 7 for(int j=i; j<=50; ++j){ 8 d[i][1][j]=1; 9 } 10 } 11 for(int j=2; j<=50; ++j){ 12 for(int i=1; i<=50; ++i){ 13 for(int k=1; k<=50; ++k){ 14 for(int first=1; first<=k; ++first){ 15 if(i-first<=0) break; 16 d[i][j][k]+=d[i-first][j-1][k]; 17 } 18 } 19 } 20 } 21 int t,n,m,k; 22 scanf("%d",&t); 23 for(int cse=1; cse<=t; ++cse){ 24 scanf("%d%d%d",&n,&m,&k); 25 printf("Case %d: %lld\n",cse,d[n][m][k]); 26 } 27 return 0; 28 }