TopCoder SRM296 DIV1 Report

來源:互聯網
上載者:User

TopCoder SRM296 DIV1 Report

match dateMonday, April 3, 2006

report dateMonday, April 10, 2006

Preface:

該好好反省了,在DIV1始終還是不能有好的表現。這次靠幾個資料Challenge了幾個代碼,但題目還是沒能做出來,看來水平還是不濟啊。

Problem 250 - NewAlbum :

貌似簡單的一道題,可以用動規快速解決,但我當時只是覺得簡單,採用了直接算的方法,沒想到這題骯髒的資料這麼多。

從i=1開始處理到nSongs張歌曲,每個i的最佳擺法是:

    best[i] = min( best[i] , best[i-j]+1 )j=1..min(i,cdCapacity)

其中j表示在best[i-j]張CD後,把j放在另一張CD內。當然必須保證j不能被13整除。

直接算也是有人過的,不過要考慮一些特殊的情況。包括如果剩下13張等待處理,而之前的CD都擺了15張時,可以從前面移一張過來,而如果前面的CD是擺放了14張的話則不行。

Problem 500 - StringReplacements:

第二題目用到了兩次遞規,看過解題報告後才知道,原來遞迴的思想是如此神奇,真該培養一下遞迴的能力了。

首先,先考慮如何計算由單個字母變化n次後的各字母數量。用一個DP數組是可以解決的。下式的mem是DP數組,t表示第t次變化,c表示從c字母開始變,i表示變成i字母。而move[i][j] 表示 i字母轉變一次後第j位的字母。

    mem[t][c][i] = sum ( mem[t-1][ move[c][k] ][i] ) k=1..3

然後考慮如何取從left到right的位置之間的字母個數,由於任意字母轉變n次後的字母個數是3^n,所以只要計算3^n與left和right的關係就可以了,同時要注意3^n可能會超出整數範圍:

long[] solve( int c, int t, long left, long right) {// 遞迴求left與right之間的解

    long[] res = new long[3];// 存放解

    long max = (long) Math.pow(3, t);// 3^t 指最大範圍

    if (left == right && left == 0 && t == 0) {// 特別處理一下只有一個字母

        res[c]++;// 且不需要變換的情況

    } else if (left <= 0 && right >= max) {// left和right的範圍很大

        return getGen(c, t);// 可以直接返回前面求的men

    } else if (left <= right) {

            int del = (int) Math.pow(3, t – 1);// 求3^(t-1),指轉變後三個之// 間的間隔

            for (int i = 0; i < 3; i++) {// 迴圈求三個子字母的解

                left = left < 0 ? 0 : left;// left保證大於等於0

                right = right > max ? max : right;// right保證小於等於最大可能

                long[] add = solve(move[c][i], t - 1, left, right);// 遞迴求一個字母解

                for (int j = 0; j < 3; j++) {

                    res[j] += add[j];// 累加解

                }

                left -= del;//left 變為下一個字母的left

                right -= del;//變為下一個字母的right

            }

        }

       return res;

}

Problem 1000 - ColoredBricks :

這題比較煩瑣,考驗編程速度和量的。首先求出所有的翻轉,共計24種,一個面可以有六個位置的可能性,這個面相鄰的面可以看出,通過一個旋轉,是有四種可能。因為只要固定了一個面和與它相鄰的那個面色子就固定了,所以6個可能乘4個可能就是24種情況。

// 301245 是從正面向上面旋轉

// 052413 是從左邊向上面旋轉

// 514302 是從左邊向正面旋轉

int[][] rotate = { { 3, 0, 1, 2, 4, 5 }, { 0, 5, 2, 4, 1, 3 },

{ 5, 1, 4, 3, 0, 2 } };

int[] rot(int[] x, int[] p) ;//旋轉函數,p是rotate中一個值,返回x轉後值

void generateRotate() {//產生24種可能

    int i, j, k, l = 0;

    int[] x = new int[] { 0, 1, 2, 3, 4, 5 };

    r = new int[24][6];

    for (i = 0; i < 4; i++) {

        x = rot(x, rotate[0]);

        for (j = 0; j < 4; j++) {

            x = rot(x, rotate[1]);

            NEXT: for (k = 0; k < 4; k++) {

                x = rot(x, rotate[2]);

                    for (int[] e : r) {

                        if (Arrays.equals(e, x))

                            continue NEXT;

                    }

                r[l++] = x.clone();

                }

            }

        }

}

下一個要考慮的問題是著色問題,一樣用暴力的方法來解決。用7層for語句對一個brick枚舉所有的著色,然後計算該著色對於所有輸入的顏色差,取一個最小值就是結果了。計算一種著色與一個輸入的顏色差需要考慮到24種旋轉。

Links:

My Blog:

http://blog.csdn.net/ray58750034/

My statistic:

http://www.topcoder.com/stat?c=coder_room_stats&rd=9817&cr=20862220

SRM 289 - Problem Set & Analysis:

http://www.topcoder.com/tc?module=Static&d1=match_editorials&d2=srm296

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.