zoukankan      html  css  js  c++  java
  • hdu1297Children’s Queue

    递推问题实现起来很简单,但得到递推公式确实很麻烦,就像DP一样。

    分析(部分出自HDU的PPT):
    设:F(n)表示n个人的合法队列,则:
    按照最后一个人的性别分析,他要么是男,要么是女,所以可以分两大类讨论: 
    1、如果n个人的合法队列的最后一个人是男,则对前面n-1个人的队列没有任何限制,他只要站在最后即可,所以,这种情况一共有F(n-1);
    2、如果n个人的合法队列的最后一个人是女,则要求队列的第n-1个人务必也是女生,这就是说,限定了最后两个人必须都是女生,这又可以分两种情况:
    (1)、如果队列的前n-2个人是合法的队列,则显然后面再加两个女生,也一定是合法的,这种情况有F(n-2);
    (2)难点在于,即使前面n-2个人不是合法的队列,加上两个女生也有可能是合法的,当然,这种长度为n-2的不合法队列,不合法的地方必须是尾巴,就是说,这里说的长度是n-2的不合法串的形式必须是“F(n-4)+男+女”,这种情况一共有F(n-4).
     
    所以递推公式为F(n)=F(n-1)+F(n-2)+F(n-4).
    另外需要注意的是 这个递推式的数据范围到了1000,int甚至long long 都已经无法承载最大边界。
     
    百度到了一个用大数处理的我能看懂的代码....

    #include<stdio.h>
    int m[1001][246];
    int main()
    {
     int i,j;
     int temp;
     int n,flag;
                               //f[n]=f[n-1]+f[n-2]+f[n-4]  用打表法
     m[1][0]=1;
     m[2][0]=2;
     m[3][0]=4;
     m[4][0]=7;
     for(i=5;i<=1001;i++)
     {
      temp=0;
      for(j=0;j<246;j++)
      {
       m[i][j]=m[i-1][j]+m[i-2][j]+m[i-4][j]+temp;       //用了数组进行大数运算,由低到高倒着排
       temp=0;
       if(m[i][j]>9)
       {
        temp=m[i][j]/10;
        m[i][j]=m[i][j]%10;
       }
      }
     }
     while(scanf("%d",&n)!=EOF)
     {
      flag=0;
      for(i=245;i>=0;i--)     //倒着输出
      {
       if(!flag&&m[n][i])
       flag=1;
       if(flag)
       printf("%d",m[n][i]);
      }
      printf(" ");
     }
    }

  • 相关阅读:
    C# WebApi 获取客户端ip地址
    C# 构造函数快捷键
    2 .SHELL 5~10节
    Spring项目集成apidoc生成api接口文档
    根据域名查找对应的ip及端口
    高质量SQL的30条建议
    1 .shell编程1~5
    CentOS7安装mysql8
    编译安Apache2.4.43报错checking for APR... no configure: error: APR not found. Please read the documentation.
    rm -rf * 的正确用法
  • 原文地址:https://www.cnblogs.com/xurenwen/p/3961895.html
Copyright © 2011-2022 走看看