2018年奇虎360春招筆試題--玫瑰花

 

這道題,第一感受想用排列組合作,可是想了很久,沒想到解決辦法(剛剛考試的時候沒有答出來)。後來想了一下應該使用動態規劃來作。優化

咱們首先分析一下狀況:spa

1.當K>N的時候,countSum = 0;code

2.當K=N的時候,countSum = N!(N的階乘)blog

3.當K>N的時候,就要經過最優子結構來進行分析了。class

前兩點易知,下面主要分析第三點。im

設F(k,n)爲n個位置,k種玫瑰的結果,則 F(k,n) = k*(F(k,n-1)+F(k-1,n-1)),分析:margin

狀況一:n-1個空缺已經放置了k種花,則新的位置放置任何一種花均可以,此時結果總數爲k*F(k,n-1);static

狀況二:n-1個空缺已經放置了k-1種花(注意!有k種選擇!),則新的位置固定須要放置剩下的那一種花,此時結果總數爲k*F(k-1,n-1);img

總數 = 狀況一 + 狀況二di

代碼以下:

public class Rose {
    public static void main(String[] args){
        System.out.println(roseSum(2,3));
    }
    
    public static long roseSum(int k,int n){
        if(k>n) return 0;
        if(k == n){
            int count = 1;
            for(int i = 0;i<n;i++)
                count*=i;
            return count;
        }
        long[][] DP = new long[k][n];
        for(int i = 0 ;i<n;i++)
            DP[0][i] = 1;
        for(int i = 1;i<k;i++)
            DP[i][0] = 0;
        for(int i = 1;i<k;i++)
            for(int j = 1;j<n;j++)
                DP[i][j] = (i+1)*(DP[i][j-1]+DP[i-1][j-1]);
        return DP[k-1][n-1]%772235;        
    }
}

 

不過此代碼雖然是使用動態規劃解決,可是空間複雜度爲O(N*K),並非最優,還可繼續優化。

優化代碼以下:

public class Rose {
    public static void main(String[] args){
        System.out.println(roseSum(2,3));
    }
    
    public static long roseSum(int k,int n){
        if(k > n) return 0;
        if(k == n){
            int count = 1;
            for(int i = 0;i<n;i++)
                count*=i;
            return count;
        }
        long[][] DP = new long[2][n];
        for(int i = 0 ;i<n;i++)
            DP[0][i] = 1;
        DP[1][0] = 0;
        for(int i = 1;i<k;i++)
            for(int j = 1;j<n;j++)
                if((i&1)==1){//此時i是奇數
                    DP[1][j] = (i+1)*(DP[1][j-1]+DP[0][j-1]);
                }else{
                    DP[0][j] = (i+1)*(DP[0][j-1]+DP[1][j-1]);
                }
        return DP[(k-1)&1][n-1]%772235;        
    }
}

 

這回的空間複雜度爲O(N)。

 

本身想出來的,不必定準確,沒通過大量試驗,若有錯誤,請各位朋友指出,謝謝~

相關文章
相關標籤/搜索