Download presentation
Presentation is loading. Please wait.
1
1 11472: Beautiful Numbers ★★★★☆ 題組: Problem Set Archive with Online Judge 題號: 11472: Beautiful Numbers 解題者:邱經達 解題日期: 2011 年 5 月 5 日 題意: 若一個 N 進位的數用到該 base 裡全部的數 字,且任兩個數字之間的差值都剛好是 1 且首位 數字不為 0 ,則該數字為 Beautiful Number 。 給定兩數 N 、 M ,分別代表 N-base 及 M 位數字, 求出在 N-base 中的數字從長度 1 到長度 M 總共出現 多少個 Beautiful Numbers 。 2<=N<=10 , 1<=M<=100 。
2
2 題意範例: N=2 , M=5 Beautiful Number 一共有以下 4 種 10,101,1010,10101 Output 4 N=3 , M=5 Beautiful Number 一共有以下 9 種 210, 1012,1210,2101, 10121,12101,21010,21012,21210 Output 9
3
3 解法: Dynamic Programming + Bitmask 使用一 3 維陣列紀錄每個 Number 的狀態及個數 BN[used_digit][length][last_digit] use_digit: 這個 Number 有用到的數字 ( 以二進位表示 ) length: 該 Number 的位元長度 last_digit: 該 Number 的最後一位數字 例: BN[00 0000 1110][6][2] 可代表 123212 、 321212 、 121232 … 等
4
4 解法: 若輸入 N=5 M=10 則答案應該會存在以下幾格 BN[00 0001 1111][length][0] BN[00 0001 1111][length][1] BN[00 0001 1111][length][2]... BN[00 0001 1111][length][9] 其中 length = 1~M ↑ 從第 1 位開始連續五個 1 也就是都使用了 01234 五個數字,長度為 length 而最後一 位數字分別從 0~9 如何計算上面那幾格的答案 ?
5
5 解法: 從個位數開始向後補位,規則為補上的數要與前一位相差 1 所以以下這些數都可能在補上一些尾數之後形成 beautiful numbers 且 * 只有 * 以下這些數才能以上述的補位規則形成 beautiful numbers 長度 12345 110101101010101 BN[0111][5][1]=2 121211012@10121@ 2211231210@10123 23210@121212101@ 332212123212121 34232123412123 BN[1110][5][3]=2 4432342101@12321 45321212112323 554323212312343 …56343232112345 …345232321010@ BN[0111][5][0]=2 …234321012@ …21210@ BN[0111][5][2]=1 … (@ 為 base-3 的 beautiful numbers)
6
6 解法範例: 由於要從個位數開始向後補位,所以初始條件則 令所有表示個位數 (0 除外 ) 的陣列值為 1 BN[used_digit][length][last_digit] BN[00 0000 0010][1][1] = 1; BN[00 0000 0100][1][2] = 1; BN[00 0000 1000][1][3] = 1;... BN[10 0000 0000][1][9] = 1;
7
7 解法範例: 則我們可以從上列中的個位數產生長度為 2 的 Numbers ,以個位數字 2 為例: 2→21 ( 補 1) 2→23 ( 補 3) 對以上的動作而言程式應該執行以下的動作 BN[00 0000 0110][2][1] += BN[00 0000 0100][1][2]; BN[00 0000 1100][2][3] += BN[00 0000 0100][1][2]; 再用長度為 2 的 Numbers 產生長度為 3 的 Numbers 21→210 ( 補 0) 21→212 ( 補 2) 對以上的動作而言程式應該執行以下的動作 BN[00 0000 0111][3][0] += BN[00 0000 0110][2][1]; BN[00 0000 1100][3][2] += BN[00 0000 0110][2][1];
8
8 解法範例: 從上列的範例可以觀察出 DP function 為 if (ld-1>=0) : BN[ used_bits | bit(ld-1) ][len+1][ld-1] += BN[used_bits][len][ld]; if (ld+1<10) : BN[ used_bits | bit(ld+1) ][len+1][ld+1] += BN[used_bits][len][ld]; 例: bit(3) = 00 0000 1000
9
9 解法範例: 用三層迴圈填完上頁的全部 BN[x][y][z] 陣列表格, x 最外層而 z 最內層, y = 1~100 、 z = 0~9 其中 x 不需要從 00 0000 0000~11 1111 1111 每個值 (1024 個 ) 都跑一遍。 從 Page.5 中的表可以知道,只有 used_bit 表示成 n 個 1 相鄰的數才有可 能向後補位形成 Beautiful Numbers ,也就是若 x 代表的 used_bits 不為 以下這些數值, BN 值必為 0 ,毋需處理 連續一個 1 連續兩個 1 連續三個 1 00 0000 000100 0000 001100 0000 0111 00 0000 001000 0000 011000 0000 1110 00 0000 010000 0000 110000 0001 1100 00 0000 100000 0001 100000 0011 1000 00 0001 000000 0011 000000 0111 0000 ……… 10 0000 000011 0000 000011 1000 0000 … 等
10
10 解法範例: 利用一陣列 b[55] 依序存放上頁中所有的 x 值,計算方法如下: 連續一個 1 ,從 b[0]~b[9] 共十個 // i = 1~9 b[0] = 1; //00 0000 0001 b[i] = b[i-1]*2; 連續兩個 1 ,從 b[10]~b[18] 共九個 // i = 11~18 b[10] = 3; //00 0000 0011 b[i] = b[i-1]*2; 連續三個 1 ,從 b[19]~b[26] 共八個 // i = 20~26 b[19] = 3; //00 0000 0111 b[i] = b[i-1]*2; 以此類推直到連續十個 1 ,一共 55 個數
11
11 解法範例: 因此填表可以改寫成 BN[ b[x] ][y][z] , 其中 x = 0 ~ 54 、 y = 1~100 、 z = 0~9 最後對輸入 N 、 M ,問題的答案為: BN[ Beautiful_Numbers_bit[N] ][m][ld] 陣列中 m = 2 ~ M 、 ld = 0 ~ 9 的所有數值之總和
12
12 解法範例: 其中 Beautiful_Numbers_bit[N] 為 N=2→00 0000 0011 N=3→00 0000 0111 N=4→00 0000 1111 N=5→00 0001 1111 N=6→00 0011 1111 N=7→00 0111 1111 N=8→00 1111 1111 N=9→01 1111 1111 N=10→11 1111 1111
13
13 討論: 時間複雜度: 需要花費最多時間的地方為填滿 BN[ b[x] ][y][z] O(x*y*z) , x = 0 ~ 54 、 y = 1~100 、 z = 0~9
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.