Bar Codes - POJ 1173 dp

来源:互联网 发布:淘宝买家微淘怎么发布 编辑:程序博客网 时间:2024/06/05 18:27

Bar Codes
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 917 Accepted: 323

Description

A bar-code symbol consists of alternating dark and light bars, starting with a dark bar on the left. Each bar is a number of units wide. Figure 1 shows a bar-code symbol consisting of 4 bars that extend over 1+2+3+1=7 units. 
 
Figure 1: Bar-code symbol over 7 units (see top) with 4 bars (see bottom)


In general, the bar code 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. For instance, the symbol in Figure 1 belongs to BC(7,4,3) but not to BC(7,4,2). 
0: 1000100  |  8: 11001001: 1000110  |  9: 11001102: 1001000  | 10: 11010003: 1001100  | 11: 11011004: 1001110  | 12: 11011105: 1011000  | 13: 11100106: 1011100  | 14: 11101007: 1100010  | 15: 1110110Figure 2: All symbols of BC(7,4,3)


Figure 2 shows all 16 symbols in BC(7,4,3). Each `1' represents a dark unit, each `0' a light unit. The symbols appear in lexicographic (dictionary) order. The number on the left of the colon (`:') is the rank of the symbol. The symbol in Figure 1 has rank 4 in BC(7,4,3). 

Input

Your program is to read from standard input. The first line contains the numbers n, k, and m (1 <= n,k,m <= 33). On the second line is a number s (0 <= s <= 100). The following s lines each contain some symbol in BC(n,k,m), represented by '0's and '1's as in Figure 2.

Output

Your program is to write to standard output. On the first line your program should write the total number of symbols in BC(n,k,m). On each of the s following lines, it should write the rank of the corresponding symbol in the input.

Sample Input

7 4 3510011101110110100110010011101000100

Sample Output

16415340

题意:有n的长度,k个木板,每个木板的长度最多为m,问有多少种组合方式,对于给定的组合是字典序的第多少个。

思路:用dp[i][j]表示后i个木板组成长度为j的有多少种情况。确定给定的组合是第几个的话,就从前往后数,奇数的木板,假如给定的长度为3,那么就答案就加上当它为1和2的时候后面的情况数,偶数的是长度从大到小加上它后面的情况。

AC代码如下:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;ll dp[40][40];int num[40];char s[110];int n,k,m;int main(){    int i,j,a,b,p,cas,pos,len;    ll ans,ret;    while(~scanf("%d%d%d",&n,&k,&m))    {        memset(dp,0,sizeof(dp));        dp[0][0]=1;        for(i=1;i<=k;i++)           for(j=1;j<=n;j++)           {               for(a=1;a<=m && j-a>=0;a++)                  dp[i][j]+=dp[i-1][j-a];           }        ans=0;        printf("%I64d\n",dp[k][n]);        scanf("%d",&cas);        while(cas--)        {            scanf("%s",s+1);            pos=0;            for(i=1;i<=k;i++)            {                pos++;                num[i]=1;                while(pos<n && s[pos]==s[pos+1])                {                    num[i]++;                    pos++;                }            }            len=n;            ans=0;            for(i=k;i>=1;i--)            {                p=k-i+1;                if(p&1)                  for(j=1;j<num[p] && len-j>0;j++)                     ans+=dp[i-1][len-j];                else                  for(j=min(m,len);j>num[p];j--)                     ans+=dp[i-1][len-j];                len-=num[p];            }            printf("%I64d\n",ans);        }    }}



0 0
原创粉丝点击