zoukankan      html  css  js  c++  java
  • rand(m)模拟rand(K)

    问题:给定一个长度N的key-value对序列,序列中的key没有重复,value赋值为正整数,例如长度为4的序列:[1:3, 2:1, 3:9, 4:6]。另外给定一个随机数生成函数rand(m)可以等概率的生成0~m-1中的任何一个整数。

    1. 请实现一个随机生成Key的函数,生成每个key的概率正比于这个key对应的value值。

              方法:首先将列表中的value加起来,比如是K;问题转化为如何利用rand(m)去模拟rand(K)的新问题,因为获得rand(K)之后便可以使用划分子区间的方法实现题目要求;

              当K<=m的时候,可以设计rand(K) 为:

              a = rand (m);
              while(a>=K)
              {
                   a=rand (m);
              }
              return a;

              当K>m && K <m*m,则构造一个rand(m*m),具体构造方法是rand(m)*m + rand (m),再利用rand(m*m) 去构造rand(K),方法也是取子区间;

         比如该题目例子中K=1+2+3+4=10,假设m=4,那么K>4&&K<16, 先用rand(4)*4+rand(4)构造出了rand(16)。然后用rand(16)构造rand(10),并且使得key值与生成key的概率成正比,那么我们可以令rand(16)=0时,输出1;rand(16)=1、2时,输出2;rand(16)=3,4,5时,输出3;rand(16)=6,7,8,9时,输出4;rand(16)=10~15时,抛弃;
              设计rand(K)为:    

     a=rand(4)*4+rand(4);
    
     while(a>=K)
    
     {
             a=rand(4)*4+rand(4);
     }
    
    switch(a):
    
    {
    
             case 0:return 1;break;
    
             case 1:
    
             case 2:return 2;break;
    
             case 3:
    
             case 4:
     
             case 5:return 3;break;
    
             case 6:
    
             case 7:
    
             case 8:
    
             case 9:return 4;break;
    
    }

              当K>m*m的时候,类似利用rand(m*m)去构建rand(m*m*m*m),再利用取子区间的方法;不再赘述

  • 相关阅读:
    重载小于号
    无聊的会议
    程序内存和时间
    对拍
    读入和输出优化
    codevs 3269 混合背包
    清北第三套题
    codevs 2188 最长上升子序列
    清北第二套题
    [COGS896] 圈奶牛
  • 原文地址:https://www.cnblogs.com/beaglebone/p/5922686.html
Copyright © 2011-2022 走看看