正整數序列 Help the needed for Dexter ,UVa 11384

題目描述 Description測試

給定正整數n,你的任務是用最少的操做次數把序列1, 2, …, n中的全部數都變成0。每次操做可從序列中選擇一個或多個整數,同時減去一個相同的正整數。好比,1,2,3能夠把2和3同時減少2,獲得1,0,1。
輸入包含多組數據。每組僅一行,爲正整數n(n≤109)。輸入結束標誌爲文件結束符(EOF)。
對於每組數據,輸出最少操做次數。spa

 輸入輸出格式 Input/output
輸入格式:
輸入包含多組數據,每組僅一行,爲正整數n(n≤10 9),輸入結束標誌爲文件結束符EOF
輸出格式:
對於每組數據,輸出最少操做次數
 輸入輸出樣例 Sample input/output
樣例測試點#1
輸入樣例:

1code

6blog

輸出樣例:
3
 
思路:書上的思路就很好,由於數據不是很大用遞歸就很快求解,代碼簡潔,這個思路挺難想的。
首先用一些比較小的數據模擬一下,當n=6時,用筆操做不難發現是3次,具體以下:
一、二、三、四、五、6
從後面三個數字,也就是四、五、6開始操做,同時減min{4,5,6},剩下:
一、二、三、0、一、2       也就是說fun(6)=fun(6/2)+1
不難發現,繼續操做前三個數一、二、3也能夠同時操做最後的一、2,因此把這五個數操做完,就是兩次:
第一次:一、0、一、0、一、0
第二次:0、0、0、0、0、0
總的來講就是3次。
 
通常的,爲了平衡,保留1~n/2,把剩下的數同時減去n/2+1,獲得序列一、二、三、…、n/二、0、一、…、(n-1)/2,等價於一、二、三、…、n/2,因此fun(n)=fun(n/2)+1,初始化fun(1)=1。
 
代碼1以下:
 1 #include <stdio.h>
 2 int fun(int n)
 3 {
 4     return n==1?1:fun(n/2)+1;
 5 }
 6 int main()
 7 {
 8     int n;
 9     scanf("%d",&n);
10     printf("%d\n",fun(n)); 
11     return 0;
12 }

代碼2以下:遞歸

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int n;
 5     while(scanf("%d",&n)!=EOF)
 6     {
 7         int ans=0;
 8         for(;n>0;n/=2)
 9             ans++;
10         printf("%d\n",ans);
11     }
12     return 0;
13 }
相關文章
相關標籤/搜索