這道題,第一感受想用排列組合作,可是想了很久,沒想到解決辦法(剛剛考試的時候沒有答出來)。後來想了一下應該使用動態規劃來作。優化
咱們首先分析一下狀況: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)。
本身想出來的,不必定準確,沒通過大量試驗,若有錯誤,請各位朋友指出,謝謝~