zoukankan      html  css  js  c++  java
  • 算法:n个骰子的点数

    题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。

     一般来说骰子点数为1~6,n个筛子的点数之和可以这样理解:第n个骰子可能出现的数与前面(n-1)个骰子和的和,前面(n-1个骰子)的和为第(n-1)个骰子可能出现的数与前面(n-2)个骰子和的和。。以此类推。以动态规划的方式求解。

    1.用递归解决

    建立一个长度[n*g_maxValue]的表,a[n]表示和为n出现的次数,除以6^n即为概率。

    #include <stdio.h>
    #include <iostream>
    #include <time.h>
    using namespace std;
    int g_maxValue = 6;//定义骰子最大值

    void getnum2(int n,int sum,int a[])
    {
    if(n==0)

    {
    a[sum]++;
    return;
    }
    for(int i=1;i<=g_maxValue;i++)
    {int temp=sum+i;

    getnum2(n-1,temp,a);//6个分支  每一个去求前面n个骰子的和,时间复杂度6的指数级递增
    }
    }

    void main()
    {
    time_t tstart=time(NULL); //获取当前时间
    int n=12;
    getnum(n);
    time_t tend=time(NULL);/获取递归结束后时间
    cout<<endl;
    cout<<tend-tstart;//打印递归时间
    }

    2.用数组的方法解决

    每增加一个骰子,即在原来的基础上增加了1~6,即和为n的数为(n-1)~(n-6)出现次数之和。

    用两个数组表示n-1个骰子的情况和n个骰子的情况。

    #include <stdio.h>
    #include <iostream>
    #include <time.h>
    using namespace std;
    int g_maxValue = 6;
    void getnum(int n)
    {
    int *allnum[2];
    allnum[0]=new int[n*g_maxValue+1];
    allnum[1]=new int[n*g_maxValue+1];
    for(int i=0;i<=n*g_maxValue;i++)
    {
    allnum[0][i]=0;
    allnum[1][i]=0;
    }
    int flag=0;
    for(int i=1;i<=g_maxValue;i++)
    allnum[flag][i] = 1;
    for(int k=2;k<=n;k++)
    {
    for(int i=k*g_maxValue;i>=k;i--)
    {
    allnum[1-flag][i]=0;

    for(int j=1;j<=i&&j<=g_maxValue;j++)
    {
    allnum[1-flag][i]=allnum[1-flag][i]+allnum[flag][i-j];
    }

    }
    for(int i=0;i<n*g_maxValue;i++)
    allnum[flag][i]=0;
    flag=1-flag;
    }
    for(int i=n;i<=n*g_maxValue;i++)
    {
    if(allnum[0][n]!=0)
    cout<<allnum[0][i]<<" ";
    else cout<<allnum[1][i]<<" ";
    }
    delete [] allnum[0];
    delete [] allnum[1];

    }


    void main()
    {
    time_t tstart=time(NULL);
    int n=12;
    getnum(n);
    time_t tend=time(NULL);;
    cout<<endl;
    cout<<tend-tstart;
    }

    方法时间差距很大,在n=12的时候,VS递归的要66s,DP的用0s。

    3.在参考的博客评论里还有个更粗暴的

    void dice1()
    {
     const int n = 6;
     int sum[n * n + 1] = {0};

     for(int i = 1; i <= n; i++)
     {
      for(int j = 1; j <= n; j++)
      {
       for(int k = 1; k <= n; k++)
       {
        for(int x = 1; x <= n; x++)
        {
         for(int y = 1; y <= n; y++)
         {
          for(int z = 1; z <= n; z++)
          {
           sum[i + j + k + x + y + z]++;
          }
         }
        }
       }
      }
     }
    }

    详情参考:http://zhedahht.blog.163.com/blog/static/254111742009101524946359/

  • 相关阅读:
    课程设计第八天,8.26
    课程设计第七天,08.25
    赖世雄英语
    英语语法-小学
    CSS(Cascading Style Sheet)
    Coredraw x7
    Servlet
    团队作业4——第一次项目冲刺(Alpha版本)2017.11.18
    团队作业4——第一次项目冲刺(Alpha版本)2017.11.16
    团队作业4——第一次项目冲刺(Alpha版本)2017.11.14
  • 原文地址:https://www.cnblogs.com/gardener/p/5985496.html
Copyright © 2011-2022 走看看