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
",cse,d[n][m][k]);
26     }
27     return 0;
28 } 
原文地址:https://www.cnblogs.com/WABoss/p/5161649.html