pku 1173 Bar Codes 经典DP,逐位确定rank

pku 1173 Bar Codes 经典DP,逐位确定rank

题意:
给出条形码系统
BC(n,k,m) is the set of all symbols with k bars that together extend over exactly n units, each bar being at most m units wide.
1、给出n,k,m,条形码第一条是黑色。问有多少种不同的划分方式。
2、给出条形码,求它的rank(字典序)
pku 1173 Bar Codes 经典DP,逐位确定rank_第1张图片
第一问应该很好解决,BC(n,k,m)=sum(BC(n-i,k-1,m)),i=1,2..m
第二问也是用经典的逐位确定的方法,唯一要注意的是,白条要从大到小累加(因为0代表白色,显然,当前条0的位数越多,字典序越小),而黑条要从小到大累加

代码:
 1 # include  < cstdio >
 2 # include  < cstring >
 3 # include  < algorithm >
 4 using   namespace  std;
 5 int  c[ 35 ][ 35 ],n,k,m;
 6 int  main()
 7 {
 8    scanf("%d%d%d",&n,&k,&m);
 9    memset(c,0,sizeof(c));
10    for(int num=1;num<=min(n,m);num++)
11       c[num][1]=1;
12    for(int num=2;num<=n;num++)
13      for(int i=2;i<=k;i++)
14        for(int j=max(1,num-m);j<num;j++)
15           c[num][i]+=c[j][i-1];
16    printf("%d\n",c[n][k]);
17    int num;
18    scanf("%d",&num);
19    while(num--)
20    {
21        char str[50];
22        char color='1';
23        int last=0,rank=0,co=1;
24        scanf("%s",str);
25        for(int i=0;i<strlen(str);i++)
26        {
27            if(str[i]!=color)
28            {
29               int len=i-last;
30               switch(color)
31               {
32                  case '1':
33                       for(int j=last+1;j<i;j++)
34                          rank+=c[n-j][k-co];
35                       color='0';
36                       break;
37                  case '0':
38                       for(int j=min(n-1,last+m);j>i;j--)
39                          rank+=c[n-j][k-co];
40                       color='1';
41                       break;
42               }
;
43               co++;
44               last=i;
45            }

46        }

47        printf("%d\n",rank);
48    }

49      return 0;
50}

51

你可能感兴趣的:(pku 1173 Bar Codes 经典DP,逐位确定rank)