• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            A Za, A Za, Fighting...

            堅信:勤能補拙

            在磕磕絆絆中,終于做完一百題,完成暑期目標,會繼續加油...

            附: summary (revision 37)

            Summary of PKU solved, since 05-20-2010

            ------------------------Fighting-----------------------------
            ------------------------Fighting-----------------------------

            [sort]
            1002 487-3279
            1007 DNA Sorting
            1468 Rectangles
            2299 Ultra-QuickSort
            2388 Who's in the Middle

            [search(dfs, bfs, backtracking)]
            1020 Anniversary Cake [good]
            1077 Eight [classic][bfs, bbfs, A*]
            1101 The Game
            1111 Image Perimeters [interesting]
            1129 Channel Allocation [classic]
            1164 The Castle
            1166 The Clocks
            1190 Birthday Cake [good]
            1198 Solitaire [classic]
            1321 Chessboard Problem
            1416 Shredding Company
            1426 Find The Multiple
            1475 Pushing Boxes [complex]
            1562 Oil Deposits
            1606 Jugs
            1629 Fillword
            1691 Painting A Board
            1724 ROADS
            1753 Flip Game
            1775 Sum of Factorials
            1915 Knight Moves
            1950 Dessert
            2248 Addition Chains
            2251 Dungeon Master
            2488 A Knight's Journey
            2531 Network Saboteur
            2676 Sudoku
            3009 Curling 2.0
            3083 Children of the Candy Corn
            3087 Shuffle'm Up
            3126 Prime Path
            3256 Cow Picnic
            3278 Catch That Cow
            3373 Changing Digits [hard]
            3411 Paid Roads
            3414 Pots

            [dynamic programming/memory function]
            1014 Dividing [good & hard]
            1015 Jury Compromise
            1050 To the Max [classic]
            1080 Human Gene Functions
            1088 Skiing [good]
            1157 Little shop of flowers
            1159 Palindrome
            1160 Post Office [good]
            1163 The Triangle
            1179 Polygon [classic]
            1185 Artillery position [classic, scdp]
            1260 Pearls [good]
            1276 Cash Machine [classic]
            1458 Common Subsequence [classic]
            1579 Function Run Fun
            1631 Bridging signals
            1887 Testing the CATCHER/2533 Longest Ordered Subsequence [classic]
            1953 World Cup Noise
            2192 Zipper
            2250 Compromise
            2479 Maximum sum/2593 Max Sequence
            3356 AGTC
            3624 Charm Bracelet

            [greedy algorithm]

            [data structure]
            1028 Web Navigation (stack/array)
            1611 The Suspects (union-find set)
            1988 Cube Stacking (union-find set)
            2524 Ubiquitous Religions (union-find set)
            3253 Fence Repair (huffman tree)
            3349 Snowflake Snow Snowflakes (Hash & Minimal Representation)

            [graph algorithm]

            [others]
            1001 Exponentiation (high precision)
            1008 Maya Calendar
            1083 Moving Tables (novel perspective) [good]
            1176 Party Lamps (enumerate)
            1226 Substrings
            1731 Orders (permutation) [good]
            2080 Calendar
            2244 Eeny Meeny Moo (Josephus Problem) [good]
            2503 Babelfish (string hash)
            2663 Tri Tiling (recurrence) [good]

            [easy/water]
            1000 A+B Problem
            1003 Hangover
            1004 Financial Management
            1005 I Think I Need a Houseboat
            1298 The Hardest Problem Ever
            1316 Self Numbers
            1477 Box of Bricks
            1543 Perfect Cubes (build table)
            1547 Clay Bully
            1552 Doubles
            1565 Skew Binary
            1595 Prime Cuts
            1936 All in All [good]
            2081 Recaman's Sequence
            2105 IP Address
            2726 Holiday Hotel [funny]

            posted @ 2010-08-19 14:47 simplyzhao 閱讀(156) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=1111

            思路:
            其實,這是一道簡單題,關鍵是要看透如何求周長: 連通塊每格四個方向(上下左右)如果不在連通塊內(超出范圍或者Empty)則周長加一
            DFS或者BFS都可以解決

            代碼:
             1 #include<stdio.h>
             2 #include<stdlib.h>
             3 #include<string.h>
             4 #define MAX_LEN 21
             5 #define is_valid(x,y) (x>=0 && x<row && y>=0 && y<col)
             6 const int dx[] = {-1100-1-111};
             7 const int dy[] = {00-11-11-11};
             8 struct Point {
             9     int x, y;
            10 }queue[MAX_LEN*MAX_LEN];
            11 char grid[MAX_LEN][MAX_LEN];
            12 int visited[MAX_LEN][MAX_LEN];
            13 int row, col, start_x, start_y;
            14 int rt;
            15 
            16 void
            17 calculate(int x, int y)
            18 {
            19     int i, tmpx, tmpy;
            20     for(i=0; i<4; i++) {
            21         tmpx = x + dx[i];
            22         tmpy = y + dy[i];
            23         if(!is_valid(tmpx, tmpy) || grid[tmpx][tmpy]=='.')
            24             ++rt;
            25     }
            26 }
            27 
            28 void
            29 bfs()
            30 {
            31     int i, head, tail, nxt_x, nxt_y;
            32     head = -1;
            33     tail = 0;
            34     queue[tail].x = start_x-1;
            35     queue[tail].y = start_y-1;
            36     visited[start_x-1][start_y-1= 1;
            37     while(head < tail) {
            38         ++head;
            39         calculate(queue[head].x, queue[head].y);
            40         for(i=0; i<8; i++) {
            41             nxt_x = queue[head].x + dx[i];
            42             nxt_y = queue[head].y + dy[i];
            43             if(is_valid(nxt_x, nxt_y) && !visited[nxt_x][nxt_y] && grid[nxt_x][nxt_y]=='X') {
            44                 ++tail;
            45                 queue[tail].x = nxt_x;
            46                 queue[tail].y = nxt_y;
            47                 visited[nxt_x][nxt_y] = 1;
            48             }
            49         }
            50     }
            51 }
            52 
            53 int
            54 main(int argc, char **argv)
            55 {
            56     int i;
            57     while(scanf("%d %d %d %d"&row, &col, &start_x, &start_y) != EOF) {
            58         if(row==0 && col==0)
            59             break;
            60         for(i=0; i<row; i++)
            61             scanf("%s", grid[i]);
            62         rt = 0;
            63         memset(visited, 0sizeof(visited));
            64         bfs();
            65         printf("%d\n", rt);
            66     }
            67 }

            posted @ 2010-08-19 14:41 simplyzhao 閱讀(195) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=2244

            參考:
            http://baike.baidu.com/view/213217.html?fromTaglist

            思路:
            從這題認識了經典的約瑟夫問題:

            無論是用鏈表實現還是用數組實現都有一個共同點:要模擬整個游戲過程,不僅程序寫起來比較煩,而且時間復雜度高達O(nm),當n,m非常大(例如上百萬,上千萬)的時候,幾乎是沒有辦法在短時間內出結果的。我們注意到原問題僅僅是要求出最后的勝利者的序號,而不是要讀者模擬整個過程。因此如果要追求效率,就要打破常規,實施一點數學策略。
            為了討論方便,先把問題稍微改變一下,并不影響原意:

            問題描述:n個人(編號0~(n-1)),從0開始報數,報到(m-1)的退出,剩下的人繼續從0開始報數。求勝利者的編號。

            我們知道第一個人(編號一定是m%n-1) 出列之后,剩下的n-1個人組成了一個新的約瑟夫環(以編號為k=m%n的人開始):
              k  k+1  k+2  ... n-2, n-1, 0, 1, 2, ... k-2
            并且從k開始報0。

            現在我們把他們的編號做一下轉換:
            k     --> 0
            k+1   --> 1
            k+2   --> 2
            ...
            ...
            k-2   --> n-2
            k-1   --> n-1

            變換后就完完全全成為了(n-1)個人報數的子問題,假如我們知道這個子問題的解:例如x是最終的勝利者,那么根據上面這個表把這個x變回去不剛好就是n個人情況的解嗎?!!變回去的公式很簡單,相信大家都可以推出來:x'=(x+k)%n

            如何知道(n-1)個人報數的問題的解?對,只要知道(n-2)個人的解就行了。(n-2)個人的解呢?當然是先求(n-3)的情況 ---- 這顯然就是一個倒推問題!好了,思路出來了,下面寫遞推公式:

            令f[i]表示i個人玩游戲報m退出最后勝利者的編號,最后的結果自然是f[n]

            遞推公式
            f[1]=0;
            f[i]=(f[i-1]+m)%i;  (i>1)

            有了這個公式,我們要做的就是從1-n順序算出f[i]的數值,最后結果是f[n]。因為實際生活中編號總是從1開始,我們輸出f[n]+1

            由于是逐級遞推,不需要保存每個f[i],程序也是異常簡單:

            #include <stdio.h>
            int main()
            {
              int n, m, i, s=0;
              printf ("N M = "); scanf("%d%d", &n, &m);
              for (i=2; i<=n; i++) s=(s+m)%i;
              printf ("The winner is %d\n", s+1);
            }

            這個算法的時間復雜度為O(n),相對于模擬算法已經有了很大的提高。算n,m等于一百萬,一千萬的情況不是問題了。可見,適當地運用數學策略,不僅可以讓編程變得簡單,而且往往會成倍地提高算法執行效率。

            代碼:

             1 #include<stdio.h>
             2 #include<stdlib.h>
             3 #include<string.h>
             4 
             5 /*
             6  * f[1] = 0
             7  * f[i] = (f[i-1]+m)%i
             8  */
             9 int
            10 josephus(int n, int m)
            11 {
            12     int i, s = 0;
            13     for(i=2; i<=n; i++
            14         s = (s+m)%i;
            15     return s+1;
            16 }
            17 
            18 int
            19 main(int argc, char **argv)
            20 {
            21     int n, m;
            22     while(scanf("%d"&n)!=EOF && n!=0) {
            23         m = 2;
            24         /* because first cut off city 1 and then begins every mth */
            25         while(josephus(n-1, m) != 1)
            26             ++m;
            27         printf("%d\n", m);
            28     }
            29 }

            posted @ 2010-08-18 21:02 simplyzhao 閱讀(229) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=1260

            思路:
            簡單DP,但是就是想不到...

            代碼:
             1 #include<stdio.h>
             2 #include<stdlib.h>
             3 #include<string.h>
             4 #define MAX_LEN 101
             5 #define INF 0x7FFFFFFF
             6 #define min(a,b) ((a)<(b) ? (a) : (b))
             7 int num[MAX_LEN], price[MAX_LEN];
             8 int sum[MAX_LEN]; /* aux */
             9 int table[MAX_LEN];
            10 int c;
            11 
            12 /*
            13  * f[i] represent the lowest possible price needed to buy list[1..i], so:
            14  *      f[i] = min (f[k] + (num[k+1]++num[i]+10)*price[i]), 0<=k<i-1
            15  */
            16 int
            17 dp()
            18 {
            19     int i, k, tmp;
            20     sum[0= 0;
            21     for(i=1; i<=c; i++)
            22         sum[i] = sum[i-1]+num[i];
            23     table[0= 0;
            24     for(i=1; i<=c; i++) {
            25         table[i] = INF;
            26         for(k=0; k<=i-1; k++) {
            27             tmp = table[k] + (sum[i]-sum[k]+10)*price[i];
            28             table[i] = min(table[i], tmp);
            29         }
            30     }
            31     return table[c];
            32 }
            33 
            34 int
            35 main(int argc, char **argv)
            36 {
            37     int i, tests;
            38     scanf("%d"&tests);
            39     while(tests--) {
            40         scanf("%d"&c);
            41         for(i=1; i<=c; i++)
            42             scanf("%d %d", num+i, price+i);
            43         printf("%d\n", dp());
            44     }
            45 }
            posted @ 2010-08-18 09:33 simplyzhao 閱讀(153) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=1179

            思路:
            這題輸在了對原題目的理解和分析上,沒能成功地走出第一步:
                                                                  將原題解析成對于表達式的求解
            把缺了一條邊的多邊形展開成直線就是一個表達式
            注意:為了求乘法,必須同時保存最大值和最小值

            f[i][j]記錄表達式中從頂點i到頂點j這段子表達式的值

            動態規劃的思想類似于矩陣連乘

            參考:
            http://hi.baidu.com/xiehuixb/blog/item/575ec81e221466c1a786699e.html

            代碼:
             1 #include<stdio.h>
             2 #include<stdlib.h>
             3 #include<string.h>
             4 #define MAX_LEN 51
             5 #define INF 9223372036854775807LL
             6 #define maximal(a, b) ((a)>(b) ? (a) : (b))
             7 #define minimal(a, b) ((a)<(b) ? (a) : (b))
             8 char operand[MAX_LEN][2];
             9 int operators[MAX_LEN];
            10 int n, ans_len, ans[MAX_LEN];
            11 long long int rt, max[MAX_LEN][MAX_LEN], min[MAX_LEN][MAX_LEN];
            12 
            13 /*
            14  * when it comes to: '+'
            15  * max[i][j] = maximal(max[i][k] + max[k+1][j])
            16  * min[i][j] = minimal(min[i][k] + min[k+1][j])
            17  *
            18  * when it comes to: '*'
            19  * max[i][j] = maximal(max[i][k]*max[k+1][j], max[i][k]*min[k+1][j], min[i][k]*max[k+1][j], min[i][k]*min[k+1][j])
            20  * min[i][j] = minimal(max[i][k]*max[k+1][j], max[i][k]*min[k+1][j], min[i][k]*max[k+1][j], min[i][k]*min[k+1][j])
            21  *
            22  * i<=k<j
            23  */
            24 void
            25 solve(char *opd, int *ops, int del_edge)
            26 {
            27     int i, j, k, len;
            28     for(i=1; i<=n; i++)
            29         max[i][i] = min[i][i] = ops[i];
            30     for(len=2; len<=n; len++) {
            31         for(i=1; i<=n-len+1; i++) {
            32             j = i+len-1;
            33             max[i][j] = -INF;
            34             min[i][j] = INF;
            35             for(k=i; k<j; k++) {
            36                 if(opd[k] == 't') {
            37                     max[i][j] = maximal(max[i][j], max[i][k]+max[k+1][j]);
            38                     min[i][j] = minimal(min[i][j], min[i][k]+min[k+1][j]);
            39                 } else { /* opd[k] == 'x' */
            40                     max[i][j] = maximal(max[i][j], max[i][k]*max[k+1][j]);
            41                     max[i][j] = maximal(max[i][j], max[i][k]*min[k+1][j]);
            42                     max[i][j] = maximal(max[i][j], min[i][k]*max[k+1][j]);
            43                     max[i][j] = maximal(max[i][j], min[i][k]*min[k+1][j]);
            44 
            45                     min[i][j] = minimal(min[i][j], max[i][k]*max[k+1][j]);
            46                     min[i][j] = minimal(min[i][j], max[i][k]*min[k+1][j]);
            47                     min[i][j] = minimal(min[i][j], min[i][k]*max[k+1][j]);
            48                     min[i][j] = minimal(min[i][j], min[i][k]*min[k+1][j]);
            49                 }
            50             }
            51         }
            52     }
            53     if(max[1][n] >= rt) {
            54         if(max[1][n] == rt)
            55             ans[ans_len++= del_edge;
            56         else {
            57             rt = max[1][n];
            58             ans_len = 0;
            59             ans[ans_len++= del_edge;
            60         }
            61     }
            62 }
            63 
            64 int
            65 main(int argc, char **argv)
            66 {
            67     int i, j, k;
            68     char tmpopd[MAX_LEN];
            69     int tmpops[MAX_LEN];
            70     while(scanf("%d"&n) != EOF) {
            71         for(i=1; i<=n; i++)
            72             scanf("%s%d", operand[i], operators+i);
            73         rt = -INF;
            74         ans_len = 0;
            75         for(i=1; i<=n; i++) {
            76             for(j=i%n+1, k=1; j!=i; j=j%n+1, k++)
            77                 tmpopd[k] = operand[j][0];
            78             tmpopd[k] = '\0';
            79             tmpops[1= operators[i];
            80             for(j=i%n+1, k=2; j!=i; j=j%n+1, k++)
            81                 tmpops[k] = operators[j];
            82             solve(tmpopd, tmpops, i);
            83         }
            84         printf("%lld\n", rt);
            85         for(i=0; i<ans_len; i++)
            86             printf("%d ", ans[i]);
            87         printf("\n");
            88     }
            89 }
            posted @ 2010-08-17 13:51 simplyzhao 閱讀(145) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=2663

            思路:
            參考: http://www.tkz.org.ru/2009-07/poj-2663-tri-tiling/

            遞推題。經典。

            本題是POJ2506 Tiling的威力加強版。由兩行變成了三行。

            推導過程與POJ2506異曲同工。

            opt[i]=3*opt[i-2]+2*opt[i-4]+2*opt[i-6]+2*opt[i-8]+……直到方括號內表達式的值為0。

            解釋一下,3*opt[i-2]是最右邊有三行2列的三種情況。

            后面的2*opt[i-X],則是最右邊有X列類似以下的結構的情況:

            X=4列的情況:2663_1.jpg;X=6列的情況2663_2.JPG;等等等等

            以上情況可以上下顛倒,故每種情況又有兩種表示,所以需要乘以2。而以上的情況從4開始,然后每次遞增2,所以遞推式中這部分從i-4開始(如果大等于0的話),每次遞減2。

            如果i為奇數,稍微推一下,可得,奇數的列數無解,答案為0。

            代碼:

             1 #include<stdio.h>
             2 #include<stdlib.h>
             3 #include<string.h>
             4 #define MAX_LEN 31
             5 long table[MAX_LEN];
             6 
             7 void
             8 build_table()
             9 {
            10     int i, j, sum;
            11     memset(table, 0sizeof(table));
            12     table[0= 1;
            13     table[2= 3;
            14     for(i=4; i<MAX_LEN; i=i+2) {
            15         sum = 3*table[i-2];
            16         for(j=4; i-j>=0; j=j+2)
            17             sum += (table[i-j]<<1);
            18         table[i] = sum;
            19     }
            20 }
            21 
            22 int
            23 main(int argc, char **argv)
            24 {
            25     int n;
            26     build_table();
            27     while(scanf("%d"&n)!=EOF && n!=-1) {
            28         printf("%ld\n", table[n]);
            29     }
            30 }

            posted @ 2010-08-16 10:44 simplyzhao 閱讀(274) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=1157

            思路:
            比較容易的動態規劃,這里提供兩種思路,其中第二種更優
            另外,居然在寫代碼的時候將0xFFFFFFFF當作最小的int值,汗...

            代碼(方案1)
             1 /* 63MS */
             2 #include<stdio.h>
             3 #include<stdlib.h>
             4 #include<string.h>
             5 #define MAX_F 101
             6 #define MAX_V 101
             7 #define INF 0xF0000000
             8 int values[MAX_F][MAX_V];
             9 int table[MAX_F][MAX_V];
            10 int f, v;
            11 
            12 /*
            13  * f[i][j] represent the maximum aesthetic values for putting the first [1..i]
            14  * bunches in the first [1..j] vases, so:
            15  *      f[i][j] = max (f[i-1][k] + tmp), i-1<=k<j
            16  */
            17 dp()
            18 {
            19     int i, j, k, p, t, up, tmp, max;
            20     table[1][1= values[1][1];
            21     for(j=2; j<=v-f+1; j++/* i = 1 */
            22         table[1][j] = values[1][j]>table[1][j-1? values[1][j] : table[1][j-1];
            23     for(i=2; i<=f; i++) {
            24         up = v-f+i;
            25         for(j=i; j<=up; j++) {
            26             max = INF;
            27             for(k=i-1; k<j; k++) {
            28                 t = values[i][k+1];
            29                 for(p=k+2; p<j; p++)
            30                     t = values[i][p] > t ? values[i][p] : t;
            31                 tmp = table[i-1][k] + t;
            32                 max = tmp > max ? tmp : max;
            33             }
            34             table[i][j] = max;
            35         }
            36     }
            37     return table[f][v];
            38 }
            39 
            40 int
            41 main(int argc, char **argv)
            42 {
            43     int i, j;
            44     while(scanf("%d %d"&f, &v)!=EOF) {
            45         for(i=1; i<=f; i++)
            46             for(j=1; j<=v; j++)
            47                 scanf("%d", values[i]+j);
            48         printf("%d\n", dp());
            49     }
            50 }

            代碼(方案2)
             1 /* 32MS */
             2 #include<stdio.h>
             3 #include<stdlib.h>
             4 #include<string.h>
             5 #define MAX_F 101
             6 #define MAX_V 101
             7 #define INF 0xF0000000
             8 int values[MAX_F][MAX_V];
             9 int table[MAX_F][MAX_V];
            10 int f, v;
            11 
            12 /*
            13  * f[i][j] represent the maximum aesthetic values for putting the i(th) bunch 
            14  * in the j(th) vases(total i bunches), so:
            15  *      f[i][j] = max(f[i-1][k])+values[i][j], i-1<=k<j
            16  */
            17 dp()
            18 {
            19     int i, j, k, up, max, rt;
            20     for(j=1; j<=v-f+1; j++
            21         table[1][j] = values[1][j];
            22     for(i=2; i<=f; i++) {
            23         up = v-f+i;
            24         for(j=i; j<=up; j++) {
            25             max = INF;
            26             for(k=i-1; k<j; k++
            27                 max = table[i-1][k] > max ? table[i-1][k] : max;
            28             table[i][j] = max+values[i][j];
            29         }
            30     }
            31     rt = INF;
            32     for(j=f; j<=v; j++)
            33         rt = table[f][j]>rt ? table[f][j] : rt;
            34     return rt;
            35 }
            36 
            37 int
            38 main(int argc, char **argv)
            39 {
            40     int i, j;
            41     while(scanf("%d %d"&f, &v)!=EOF) {
            42         for(i=1; i<=f; i++)
            43             for(j=1; j<=v; j++)
            44                 scanf("%d", values[i]+j);
            45         printf("%d\n", dp());
            46     }
            47 }
            posted @ 2010-08-15 11:16 simplyzhao 閱讀(124) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=1731

            思路:
            求全排列,這個問題本身挺簡單,不過題目要求: a. 不能重復;b. 有序輸出
            記得曾經做過這題,當時偷懶用STL過的(真要自己寫,估計當時也不會(*^__^*) 嘻嘻……)
            現在,決心棄用C++來做題,好好鍛煉基本功,所以就硬著頭皮自己慢慢寫
            好在前段時間對于搜索題有了一定的積累,否則相信自己肯定還是不知道怎么寫的
            找個例子,畫出遞歸調用樹,對于理解有很大幫助

            純C遞歸實現如下:
            代碼:
             1 /* 364K 454MS */
             2 #include<stdio.h>
             3 #include<stdlib.h>
             4 #include<string.h>
             5 #define MAX_LEN 201
             6 char str[MAX_LEN];
             7 int len;
             8 
             9 int
            10 compare(const void *arg1, const void *arg2) /* for qsort */
            11 {
            12     return *((char *)arg1) - *((char *)arg2);
            13 }
            14 
            15 void
            16 swap(char *seq, int i, int j) /* exchange */
            17 {
            18     char tmp = seq[i];
            19     seq[i] = seq[j];
            20     seq[j] = tmp;
            21 }
            22 
            23 void
            24 perm(char *seq, int begin, int end)
            25 {
            26     int i, j, tmp;
            27     char pre=0;
            28     if(begin >= end) {
            29         printf("%s\n", seq);
            30         return;
            31     }
            32     for(i=begin; i<=end; i++) {
            33         if(i>begin && seq[i]==seq[begin]) /* avoid duplicates */
            34             continue;
            35         if(pre == seq[i]) /* avoid duplicate */
            36             continue;
            37         /* in order to keep the alphabetical order */
            38         tmp = seq[i];
            39         for(j=i; j>begin; j--)
            40             seq[j] = seq[j-1];
            41         seq[begin] = tmp;
            42         perm(seq, begin+1, end);
            43         tmp = seq[begin];
            44         for(j=begin; j<i; j++)
            45             seq[j] = seq[j+1];
            46         seq[i] = tmp;
            47         /*
            48         swap(seq, begin, i);
            49         perm(seq, begin+1, end);
            50         swap(seq, begin, i);
            51         */
            52         pre = seq[i];
            53     }
            54 }
            55 
            56 int
            57 main(int argc, char **argv)
            58 {
            59     while(scanf("%s", str) != EOF) {
            60         len = strlen(str);
            61         qsort(str, len, sizeof(char), compare);
            62         perm(str, 0, len-1);
            63     }
            64 }



            posted @ 2010-08-15 09:10 simplyzhao 閱讀(116) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=1631

            思路:
            題意理解清楚,其實就是找出最長上升子序列
            這里采用O(nlogn)的算法,類似于貪心的原理,關鍵是要理解輔助數組aux[]的含義,aux[len]所代表的是組成長度為len的最長上升子序列的尾元素的最小值

            下面的內容轉自: http://blog.csdn.net/ottoCho/archive/2009/12/02/4927262.aspx
            O(n*log n)算法分析如下:

            設 A[t]表示序列中的第t個數,F[t]表示從1到t這一段中以t結尾的最長上升子序列的長度,初始時設F [t] = 0(t = 1, 2, ..., len(A))。則有動態規劃方程:F[t] = max{1, F[j] + 1} (j = 1, 2, ..., t - 1, 且A[j] < A[t])。 

            現在,我們仔細考慮計算F[t]時的情況。假設有兩個元素A[x]和A[y],滿足 
            (1)x < y < t  (這里應該錯了,如果x<y<t成立,那么F[y]>=F[x]+1,不可能有(3)成立,這里應該是y<x<t) [by simplyzhao, 2010-10-19]
            (2)A[x] < A[y] < A[t] 
            (3)F[x] = F[y] 
            此時,選擇F[x]和選擇F[y]都可以得到同樣的F[t]值,那么,在最長上升子序列的這個位置中,應該選擇A[x]還是應該選擇A[y]呢? 
            很明顯,選擇A[x]比選擇A[y]要好。因為由于條件(2),在A[x+1] ... A[t-1]這一段中,如果存在A[z],A[x] < A[z] < a[y],則與選擇A[y]相比,將會得到更長的上升子序列。 
            再根據條件(3),我們會得到一個啟示:根據F[]的值進行分類。對于F[]的每一個取值k,我們只需要保留滿足F[t] = k的所有A[t]中的最小值。設D[k]記錄這個值,即D[k] = min{A[t]} (F[t] = k)。 

            注意到D[]的兩個特點: 
            (1) D[k]的值是在整個計算過程中是單調不上升的。 
            (2) D[]的值是有序的,即D[1] < D[2] < D[3] < ... < D[n]。 

            利 用D[],我們可以得到另外一種計算最長上升子序列長度的方法。設當前已經求出的最長上升子序列長度為len。先判斷A[t]與D[len]。若A [t] > D[len],則將A[t]接在D[len]后將得到一個更長的上升子序列,len = len + 1, D[len] = A [t];否則,在D[1]..D[len]中,找到最大的j,滿足D[j] < A[t]。令k = j + 1,則有A [t] <= D[k],將A[t]接在D[j]后將得到一個更長的上升子序列,更新D[k] = A[t]。最后,len即為所要求的最長上 升子序列的長度。 

            在 上述算法中,若使用樸素的順序查找在D[1]..D[len]查找,由于共有O(n)個元素需要計算,每次計算時的復雜度是O(n),則整個算法的 時間復雜度為O(n^2),與原來的算法相比沒有任何進步。但是由于D[]的特點(2),我們在D[]中查找時,可以使用二分查找高效地完成,則整個算法 的時間復雜度下降為O(nlogn),有了非常顯著的提高。需要注意的是,D[]在算法結束后記錄的并不是一個符合題意的最長上升子序列!

            代碼:
             1 /* O(nlogn) algorithm: the longest increasing sub-sequence [LIS] */
             2 #include<stdio.h>
             3 #include<stdlib.h>
             4 #include<string.h>
             5 #define MAX_LEN 40001
             6 int num[MAX_LEN];
             7 int aux[MAX_LEN];
             8 int size, rt_len;
             9 
            10 int
            11 dp()
            12 {
            13     int i, left, right, mid;
            14     rt_len = 1;
            15     aux[rt_len] = num[0];
            16     for(i=1; i<size; i++) {
            17         if(num[i] > aux[rt_len]) {
            18             ++rt_len;
            19             aux[rt_len] = num[i];
            20         } else {
            21             /* binary search: O(logn) */
            22             left = 1;
            23             right = rt_len;
            24             while(left <= right) {
            25                 mid = (left+right)/2;
            26                 if(num[i]>aux[mid])
            27                     left = mid+1;
            28                 else
            29                     right = mid-1;
            30             }
            31             aux[left] = num[i];
            32         }
            33     }
            34     return rt_len;
            35 }
            36 
            37 int
            38 main(int argc, char **argv)
            39 {
            40     int i, tests;
            41     scanf("%d"&tests);
            42     while(tests--) {
            43         scanf("%d"&size);
            44         for(i=0; i<size; i++)
            45             scanf("%d", num+i);
            46         printf("%d\n", dp());
            47     }
            48 }
            posted @ 2010-08-14 21:09 simplyzhao 閱讀(346) | 評論 (0)編輯 收藏
            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=1887
            http://acm.pku.edu.cn/JudgeOnline/problem?id=2533

            思路:
            典型而簡單的動態規劃,類似于最大子段和的思想:

                                         f[i]表示以num[i]結尾的最長下降(上升)子序列,那么:
                                              f[i] = max (f[j]+1, if num[j]>num[i] && 0<=j<i)
            原本挺簡單的代碼,一會就寫完了,結果卻因為一個臨時變量的初始化錯誤而WA了好多次,要細心...
            上述是O(n^2)的算法,另外還有O(nlgn)的算法,下回嘗試。

            代碼(pku 1887):
             1 #include<stdio.h>
             2 #include<stdlib.h>
             3 #include<string.h>
             4 #define MAX_LEN 32767
             5 int num[MAX_LEN];
             6 int max[MAX_LEN];
             7 int len;
             8 
             9 /*
            10  * f[i] represent the longest descent sequence ended with num[i], so:
            11  *      f[i] = max ( f[j]+1, if num[j]>num[i], 0<=j<i)
            12  */
            13 int
            14 dp()
            15 {
            16     int i, j, t, rt;
            17     max[0= rt = 1;
            18     for(i=1; i<len; i++) {
            19         t = 1/* WA twice here, for t=-1 */
            20         for(j=0; j<i; j++) {
            21             if(num[j] > num[i])
            22                 t = max[j]+1>? max[j]+1 : t;
            23         }
            24         max[i] = t;
            25         rt = max[i]>rt ? max[i] : rt;
            26     }
            27     return rt;
            28 }
            29 
            30 int
            31 main(int argc, char **argv)
            32 {
            33     int i, tmp, cnt = 0;
            34     while(scanf("%d"&tmp)!=EOF && tmp!=-1) {
            35         num[0= tmp;
            36         len = 1;
            37         while(scanf("%d", num+len)!=EOF && num[len]!=-1)
            38             ++len;
            39         printf("Test #%d:\n  maximum possible interceptions: %d\n\n"++cnt, dp());
            40     }
            41 }
            posted @ 2010-08-14 11:04 simplyzhao 閱讀(194) | 評論 (0)編輯 收藏
            僅列出標題
            共21頁: First 10 11 12 13 14 15 16 17 18 Last 

            導航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久婷婷国产综合精品| 国内精品久久久久| 亚洲精品成人网久久久久久| 久久91精品国产91久| 无码人妻久久一区二区三区蜜桃| 伊人久久大香线蕉av不变影院| 精品久久8x国产免费观看| 久久精品成人| 韩国免费A级毛片久久| 国产精品亚洲综合专区片高清久久久| 久久久久亚洲av毛片大| 亚洲国产精品高清久久久| 久久本道久久综合伊人| 无码人妻久久一区二区三区免费丨| 久久久久中文字幕| 亚洲女久久久噜噜噜熟女| 午夜精品久久久久9999高清| 国内精品久久久久影院免费| 色欲久久久天天天综合网精品| 久久综合色区| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久精品嫩草影院| 天天综合久久一二三区| 91久久成人免费| 国产精品久久久久…| 97久久国产综合精品女不卡| 久久一区二区三区99| 亚洲国产精品久久| 狠狠色丁香久久婷婷综| 亚洲精品无码成人片久久| 久久亚洲AV无码精品色午夜| 欧美性猛交xxxx免费看久久久| 久久中文娱乐网| 久久久久免费精品国产| 国产AⅤ精品一区二区三区久久 | 久久久久国产精品三级网| 久久国产精品国产自线拍免费| 97精品伊人久久大香线蕉app| 亚洲人成伊人成综合网久久久| 国产精品久久久香蕉| 77777亚洲午夜久久多人|