法則分析
Final Project
   第8組


陳境峰 9677613
駱俊綱 9677604

授課教師:陳元賀
                Jan. 10, 2013.
題目:




      Jan. 10, 2013.
輸入說 明 :
每 一行 代表一幸運門問題,分別輸入上述
三個正整數 n s k ,均以空格隔開, 0 0 0
代表結束。

輸出說 明 :
就每 一問題輸出如下:( 1 )第 k 個幸運
門開啟 的組合 ; 及( 2 )所得金 額總和。


                    Jan. 10, 2013.
輸入範例 :
424
526
7 3 10
000

輸出範例 :
OCCO = $900
COOCC = $1200
CCOOOCC = $2800
                  Jan. 10, 2013.
設計理念:




     Total bones 排序的方式

Key point :
※ 直接選取有編號最大的門在內 之組合,就可以得到
最高的獎金。
※ 以這個邏輯下去選取來達到排序的目的,因此不必
另 外加以排序。



                         Jan. 10, 2013.
(期中)設計理念:
第 K 個的選取
(1)
k-(n-s+1)
if < 0 ,open door 1
if > 0
->k - ( n - s + 1 ) - ( n - s )
  if > 0 , open door 2
         .
         .
         .
                                  Jan. 10, 2013.
(期中)設計理念:
第 K 個的選取
(2)
k - ( n - s + 1 ) - ( n - s ) – ( n - s - 1 )……
 [ open door 1 的餘數繼續往下減 ]

 if < 0 , open door 2
 if > 0
 -> k - ( n - s + 1 ) - ( n - s )……



                                          Jan. 10, 2013.
(期中)設計理念:
第 K 個的選取
(k)
k - ( n - s + 1 ) - ( n - s ) – ( n - s - 1 )……
 [ open door k-1 的餘數繼續往下減 ]

if < 0 , open door k
if > 0
-> k - ( n - s + 1 ) - ( n - s )……
Now numberassignation = 0
So we choose the k doors!
                                          Jan. 10, 2013.
設計理念修正:

• 經過期中過後實作發現,期中報告時
  的思考方向有錯誤,所以在期末時加
  以修正,並經過實作驗證後,得出我
  們想要的答案。
• 依據 2m > 2m-1+2m-2+…22+21 的想法選
  擇,由指數的大小組合決定總金額的
  排序,可省去計算各組合的總金額之
  後排序的問題。



                         Jan. 10, 2013.
設計理念修正:
• 如上頁所示,最大總金額之組合為第 m 扇門
  、第 m-1 扇門、…、第 m-n+2 扇門、第 m-n
  + 1 扇門。
• 第二大組合為第 m 扇門、第 m-1 扇門、…、
  第 m-n+2 扇門、第 m-n 扇門。
• 第 m-n+1 大組合為第 m 扇門、第 m-1 扇門、
  …、第 m-n+2 扇門、第 1 扇門。
• 第 m-n+2 大組合為第 m 扇門、第 m-1 扇門、
  …、第 m-n + 1 扇門、第 m-n 扇門。
• 依此類推…
• 所以,
                        Jan. 10, 2013.
題目實做:


                  ………………


  第   第     第     ………………   第
  m   m-1   m-2            1
  門   門     門              門
在 M 個門中,選取 N 個門,將所有可能組合的獎金
計算並排序,並指出排序第 K 個大的獎金金額及其門
的組合。


                           Jan. 10, 2013.
Initial doorLocation = m // 從第 K 扇門開始選取
Initial setDoors = 1 // 計算第 1 扇要選的門
while(N > 0){
         count setCountResult by setCount();
         while(K > setCountResult){
                doorLocation--; // 不包含第 m 門,計算 m-1
扇
                count setCountResult by setCount(); 
         }
         // 包含第 doorLocation 扇門
          setCountResult -= setCount(doorLocation);
         // 將包含第 doorLocation 扇門的 setCountResult 減
去
         chooseDoors[setDoors++] = doorLocation;
         // 將包含的門紀錄至選取表單,計算下一扇要選
的門
         stateDoor[doorLocation] = 1; // 將要選的門狀態設    Jan. 10, 2013.
題目實做:欲選取的編號計算




                                 setcount


1.1 、 if k > setcount ,表示第 k 組值 小於第
setcount
     組的值 ,故第 k 組不包含第 m 個門。

1.2 、 if k < setcount ,表示第 k 組包含第 m 個門
。
                                   Jan. 10, 2013.
題目實做:欲選取的編號計算
2 、續 1




                     setcount




                  Jan. 10, 2013.
題目實做:欲選取的編號計算


3 、已完成開門及關門的表格,在 doorprint 中依
「0」
   或「 C 」列印,並依「 0 」的值 計算該門的值 後
依
   序加總。




                         Jan. 10, 2013.
double orderCount(int order)
{
  initial orderMax = 1 // 由 1 階開始
  static orderedRecord // 靜態紀錄
  if(orderMax == 1){ // 第一次計算
     initial orderedRecord[1~ order] = 1;  //  初始化階乘表
     }
  }
  if(orderedRecord[order] == 1 && order > 1){  // 判斷無紀錄
     for(i from orderMax + 1 to order){ // 從已有之紀錄開始計算
        orderedRecord[i] = i * orderedRecord[i - 1]; / 計算階乘,紀
錄
     }
  }
  else{ // 判斷有紀錄
    return orderedRecord[order]; // 直接回傳紀錄
  }                                                     Jan. 10, 2013.
題目實做:階乘的計算
• 計算統計數量的函式,若是單純使用迴圈
  或是遞迴方式,並不紀錄 ,則將會增 加計
  算次數。
• 使用 Dynamic Programing 的方式,將已
  經計算過的組合數以查 表方式直接傳回,
  節省計算的次數。
• 若是查 無紀錄 資料,則由前次最大紀錄 繼
  續往上計算,求得新的最大紀錄 。
• 以靜態資料儲存,單次執行中可重複使用
  。
                         Jan. 10, 2013.
                                    17
double doorPrint(int number, int *array)
{
      int i;
      double bouns = 0;

       for(i = 1; i <= number; i++){
                if(array[i] == 1){
                        printf("O");
                        bouns += (pow(2, i - 1) * 100);
                }
                else{
                        printf("C");
                }
       }
       return bouns;
}
                                                      Jan. 10, 2013.
題目實做:狀 態列印及總金額計算
doorChoose(numberDoor[i], numberOpens[i],
numberAssignation[i], chooseDoors, stateDoor, i);

選取的計算使用 doorChoose 函式進行。

totlaBonus = doorPrint(numberDoor[i],
stateDoor, i);

計算出來後,由 doorPrint 函式列印並計算總金
額


                                        Jan. 10, 2013.
空間複雜度:




         Jan. 10, 2013.
                    20
空間複雜度: A




           Jan. 10, 2013.
空間複雜度: B




           Jan. 10, 2013.
                      22
空間複雜度: C




           Jan. 10, 2013.
                      23
執行成果




       Jan. 10, 2013.
Source Code :
http://codepad.org/XC1CUwzO
https://www.dropbox.com/s/s122eb6wyzsrm4g/Project.c
https://docs.google.com/open?id=0B8flbU312fOqbjRCYlF5bC1nZ00
http://ppt.cc/6zVz

Execute file :
X64  
http://ppt.cc/DhR~
https://www.dropbox.com/s/f1l7qg7c34ygf4g/Project_x64.exe
X32
http://ppt.cc/KXiM
https://www.dropbox.com/s/02ron8kfa299kqr/Project_x32.exe




                                                    Jan. 10, 2013.

Project final no.8