[演算法] 固定的元素在固定長度上進行全排列

orchid發表於2014-10-14

題目1:列印從1到最大n位數的所有數字。比如n是3,則列印1,2,3,4...999。

題目2:把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,列印出s的所有可能值出現的概率。

----------------

對於題目1,由於n的值可能會很大,所以直接print是不行的,沒有一個資料型別可以承載大n。對於題目2,求概率就是求點數和為s的投擲出現的次數。這兩個題目有一個共同點,它們都與一種序列有關係,這個序列可以描述為:有n個盒子,每個盒子裡面都可以放x1到xn的任意一個數,輸出所有可能的排放方式(可能要求有序)。對於題目1,就是有n個盒子,每個盒子裡面放入0-9的任意一個數,列印序列。對於題目2,就是n個盒子,每個盒子裡面放入1-6的任意一個數,統計盒子內元素的和的出現次數。

---------------

題目1的虛擬碼:

int* S=new int[n+1];  //用S[n]記錄第n位,S就是那個盒子
void printN(int n)  //列印1到最大n位整數
{
  for(int i=0;i<10;i++)
 {
     S[n]=i;
     if(n>1)
    {
        printN(n-1);
    }  
    else if(n==1)
    {
         print(S);  //可能還需要些處理,倒過來,去打掉不需要的0等
    }
 }    
}    

對於題目2,我們不需要用一個陣列表示出盒子,因為我們不關係盒子裡的東西具體是什麼,我們只關心裡面元素的和。

void getAppearTimes(int n,int end,int curSum,int* probility)
{

    for(int i=1;i<=6;i++)
    {
        if(end==0)
        {
            //probility[i]儲存和為i的投擲出現次數
            probility[curSum+i]++;
        }
        else
        {
            getAppearTimes(n,end-1,curSum+i,probility);
        }
    }
}

 

相關文章