每日一算法:百元百雞

100元買100只,題目:公雞5元一隻、母雞3元一隻、小雞1元三隻
求100元買一百隻,各可以買幾隻
三個變量:公雞數量爲 x 母雞數量爲 y 小雞數量爲 z
滿足條件:
①:x+y+z=100  
②:5x+3y+z/3=100

以上爲計算題目得出方程


/**
 * 公雞5元一隻、母雞3元一隻、小雞1元三隻
 * 求100元買一百隻,各可以買幾隻
 * 三個變量:公雞數量爲 x 母雞數量爲 y 小雞數量爲 z
 * 滿足條件:x+y+z=100   5x+3y+z/3=100
 * 以上爲計算題目得出方程
 */
void bj(int amount, int num) {
    int x, y, z = 0;
    // 公雞數量
    for (x = 0; x <= num; x++) {
        // 母雞數量
        for (y = 0; y <= num; y++) {
            // 小雞數量
            z = num - x - y;
            // 滿足條件的
            if (z % 3 == 0 && x * 5 + y * 3 + z / 3 == amount) {
                printf("公雞:%d,母雞:%d,小雞:%d\n", x, y, z);
            }
        }
    }
}
int main(){
    bj(100,100);
    return 0;
}

以上不是最優的辦法,因爲最外層循環了 num 次,第二層循環也循環了 num次,這裏可以得到一部分優化

void bj(int amount, int num) {
    int x, y, z = 0;
    // 公雞數量
    for (x = 0; x <= num / 5; x++) {
        // 母雞數量
        for (y = 0; y <= num / 3; y++) {
            // 小雞數量
            z = num - x - y;
            // 滿足條件的
            if (z % 3 == 0 && x * 5 + y * 3 + z / 3 == amount) {
                printf("公雞:%d,母雞:%d,小雞:%d\n", x, y, z);
            }
        }
    }
}

int main() {
    bj(100, 100);
    return 0;
}


這樣的優化我們不必需要兩個循環都循環num次了,只要循環符合amount的最大數,這樣可以避免過多不必要的循環。
這樣就是最優的解法了嗎?當然不是,我們這裏可以看到時間複雜度是:O(N2),那我們有沒有辦法優化到O(N)呢?

我們來看看結果:

公雞:0,母雞:25,小雞:75
公雞:4,母雞:18,小雞:78
公雞:8,母雞:11,小雞:81
公雞:12,母雞:4,小雞:84我們來找一下規律,在這四條結果中,公雞的規律是4的倍數,母雞是7的遞減,小雞是3的遞增。
我們還記得在一開始的時候提到的方程組:
①:x+y+z=100  
②:5x+3y+z/3=100
上面兩個方程組,有三個未知變量,爲不定方程組
令②×3-①得:7x+4y=100
由 x+y+z = 100和5x + 3y + z/3 = 100可得7x+4y=100
則y = 25  -(7/4)X
再令x = 4k,則有y = 25 - 7k,繼而z = 75 + 3k
因爲  0 =<  z <= 100,所以k的可能取值是0,1,2,3

 

void bj(int amount, int num) {
    int x, y, z = 0;
    for (int k = 1; k <= 3; k++) {
        x = 4*k;
        y = 25-7*k;
        z = 75+3*k;
        printf("公雞:%d,母雞:%d,小雞:%d\n", x, y, z);
    }
}

int main() {
    bj(100, 100);
    return 0;
}

以上的時間複雜度就可以爲O(N)


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章