poj1173 解题报告2013-07-21 13:31 by 期待 、, 42 阅读, 0 评论, 收藏编辑

http://poj.org/problem?id=1173

发现此题资料甚少,斗胆第一次写一份解题报告
【题意】
    输入 n(代表二进制位数) k(代表黑条白条总共有几条,条形码是以黑条开始的,再白黑交替出现) m(代表每条最多占多少个二进制位)

输出这种模式的条形码的有多少个?
     
    输入s,再输入s个二进制形式的条形码
    输出每个条形码在该模式中的序号,序号是根据二进制条形码的十进制数值排序,序号从0开始。

【解题思路】
    动态规划+组合数学。
     我们举一个例子:n=7,k=4,m=3。
   ⑴计算个数
    要计算此模式条形码的数量,那么我们只要分别计算出
            n=6,k=3,m=3。
            n=5,k=3,m=3。
            n=4,k=3 ,m=3。
   再讲他们相加即可。
   扩展到一般,得公式 [n,k] = ∑[n-i,k-1](i = 1,2···m-1,m)
   根据推算,我们可以将公式化简成  [n,k] = [n-1,k] + [n-1,k-1] - [n-m-1,k-1] 
    我们令[0,0]=1,   令 [0,1]至[0,k]  和 [1,0]至[k,0] =0,其余的值都可以通过递推得到

⑵计算序号
    首先将 长度为n的二进制条形码 转换成 长度为k的向量,例如 1101110 -》 2131(2个1,1个0,3个1,1个0)
    2131之前的条形码可以分为四部分:
        1???    [6,3] = 7
        22??    [3,2] = 1
        23??    [2,2] = 2
        211?    [3,1] = 1
        212?    [2,1] = 1
       合计为12    对照下面题目给出的表 确是如此    
        至于究竟上面是如何弄出来的,需要分黑条和白条分别考虑,不是很好说明,看代码应该能懂。
        还有一点,我们都知道0在二进制位里面越前,1越后,则该数值会越小(即序号越小)。

0: 1000100 | 8: 1100100
1: 1000110 | 9: 1100110
2: 1001000 | 10: 1101000
3: 1001100 | 11: 1101100
4: 1001110 | 12: 1101110
5: 1011000 | 13: 1110010
6: 1011100 | 14: 1110100
7: 1100010 | 15: 1110110

【代码】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
using namespace std;
  
int n,k,m;
int dp[40][40]={0};//下标分别对应着 n+1 和 k+1
int s;
char bin[40];//存储每次输入的二进制串
int vec[40];//将二进制的bin数组 转换成 k部分的向量
int count[102];
  
void table()//打表 计算还剩 n位 和 k部分时 有多少种情况
{
    dp[0][0]=1;
    for(int j=1;j<=k;j++)//一列列的计算
        for(int i=1;i<=n;i++)
        {
            dp[i][j]=dp[i-1][j]+dp[i-1][j-1];//等于 左上和上面 这2个之和
            if(i-m-1>=0)
                dp[i][j]-=dp[i-m-1][j-1];
        }
}
  
void binToVec()//将二进制的bin数组 转换成 k部分的向量 并且保存到vec数组中
{
    int c=0;
    char first;
    for(int i=0,j=0;i<n;i--)
    {
        c=1;
        first=bin[i++];
        while(bin[i++]==first)
        {
            c++;
        }
        vec[j++]=c;
    }
}
  
int countOrder()//计算该二进制的序号
{
    int count = 0;
    for(int i=0,u=n;i<k-1;i++)
    {
        if(i%2==0)//针对编码为1的部分
        {
            for(int j=1;j<vec[i];j++)
            {
                if(u>=j)
                    count+=dp[u-j][k-i-1];
            }
        }
        else//针对编码为0的部分
        {
            for(int j=m;j>vec[i];j--)
            {
                if(u>=j)
                    count+=dp[u-j][k-i-1];
            }
        }
        u-=vec[i];
    }
    return count;
}
  
int main()
{
    cin>>n>>k>>m;
    table();
    cin>>s;
    for(int i=0;i<s;i++)
    {
        cin>>bin;
        binToVec();
        count[i] = countOrder();
    }
    cout<<dp[n][k]<<endl;//输出总共有多少种
    for(int i=0;i<s;i++)//输出相应二进制编码的序号
    {
        cout<<count[i]<<endl;
    }
}

  

【转载请注明出处】
http://www.cnblogs.com/hezhichao/p/3203639.html

http://user.qzone.qq.com/454822252/blog/1374384518#!app=2&via=QZ.HashRefresh&pos=1374384518

 
 

poj1173 解题报告的更多相关文章

  1. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  2. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  3. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  4. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  5. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  6. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  7. 习题:codevs 1519 过路费 解题报告

    今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...

  8. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  9. LeetCode 解题报告索引

    最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中......                        ...

随机推荐

  1. 基于C++ 苹果apns消息推送实现(2)

    1.该模块的用途C++ 和 Openssl 代码 它实现了一个简单的apns顾客 2.配套文件:基于boost 的苹果apns消息推送实现(1) 3.最初使用的sslv23/sslv2/sslv3仅仅 ...

  2. Android开发:怎样定制界面风格

    统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).OPhone系统提供了很多系统默认的风格和主题,但是很多情况下,这些不能满足我们的需 ...

  3. 快速构建Windows 8风格应用8-贴靠视图

    原文:快速构建Windows 8风格应用8-贴靠视图 本篇博文主要介绍如何切换出贴靠视图.关于贴靠视图的设计.关于贴靠视图的应用程序栏和如何实现贴靠视图. 如何切换出贴靠视图 第一步:水平方向全屏视图 ...

  4. GitHub上整理

    GitHub上整理 技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应 ...

  5. Visual Studio测试工具TestDriven.NET2.2

    原文:Visual Studio测试工具TestDriven.NET2.2 关于TestDriven.NET的文章很多,有很详细的说明,我不太会单元测试只是每次要运行程序才能调试觉得太麻烦了,所以找了 ...

  6. Visual Studio 中的单元测试 UNIT TEST

    原文:Visual Studio 中的单元测试 UNIT TEST 注:本文系作者原创,可随意转载,但请注明出处.如实在不愿注明可留空,强烈反对更改原创出处.TDD(Test-Driven Devel ...

  7. 基于Asterisk的VoIP开发指南——(2)Asterisk AGI程序编写指南

    原文:基于Asterisk的VoIP开发指南--(2)Asterisk AGI程序编写指南 5. Asterisk AGI程序编写指南 5.1概述 很多时候,我们需要在拨号方案中做某些业务逻辑的判断或 ...

  8. 怎样使用万用表来测试板子上的TX和RX引脚

    最近在看openwrt时看到的一个方法,直接看下面写的: 文章来自:http://wiki.openwrt.org/doc/hardware/port.serial 经实际测试时发现,将万用表的负表笔 ...

  9. POJ 3602 Typographical Ligatures

    [题意简述]:题意就是输入一串字符串,问我们有多少种不同的字符,也就是说出现过一次的字符,下次就不记到种数中了,特别的有  ff, fi ,fl ,ffi ,ffl,'',``, 这几个每一个算是一种 ...

  10. EnterpriseLibrary 6.0(微软企业库6.0学习笔记) 之Data Access Block 配置和获取链接字符串

    EnterpriseLibrary 的特点是快速开发,融合了微软工程师多年的经验,现在在微软内部有专门的一个小组在完善EnterpriseLibray,最近的更新时间是April 2013. 相关链接 ...