動態規劃——Russian Doll Envelopes
阿新 • • 發佈:2018-11-11
這個題大意很好理解,通過例子就能明白,很像俄羅斯套娃,大的娃娃套小的娃娃。這個題是大信封套小信封,每個信封都有長和寬,如果A信封的長和寬都要比B信封的要大,那麼A信封可以套B信封,現在給定一組信封的大小,要求輸出最多有幾個信封能套在一起。
Example:
Given envelopes = [[5,4],[6,4],[6,7],[2,3]], the maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]). 這個題細想其實很簡單,首先要排序,按長從小到大排列,如果長一樣,視寬小的為小排在前面。這樣一來最優子結構和狀態轉移就都有了。
狀態:dp[i]表示包含了第i的信封的ans,狀態轉移方程:如果第i個信封能套下它前面的第j個信封,則dp[i] = max{dp[j]+1},0<=j<i,否則dp[i] = 1只包含自身。 這個題的關鍵其實是前面排序那部分,我隨便寫了個冒泡O(n^2)的排序,還算運氣好直接ac了。
Given envelopes = [[5,4],[6,4],[6,7],[2,3]], the maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]). 這個題細想其實很簡單,首先要排序,按長從小到大排列,如果長一樣,視寬小的為小排在前面。這樣一來最優子結構和狀態轉移就都有了。
狀態:dp[i]表示包含了第i的信封的ans,狀態轉移方程:如果第i個信封能套下它前面的第j個信封,則dp[i] = max{dp[j]+1},0<=j<i,否則dp[i] = 1只包含自身。 這個題的關鍵其實是前面排序那部分,我隨便寫了個冒泡O(n^2)的排序,還算運氣好直接ac了。
1public int maxEnvelopes(int[][]envelopes) { 2 int esize = envelopes.length; 3 if(esize==0)return 0; 4 if(esize==1)return 1; 5 int ans = 1; 6 int t1 = 0,t2 = 0; 7 for(int i = esize-1;i>0;i--) { 8 for(int j = 0;j<i;j++) { 9 if(envelopes[j][0]>envelopes[j+1][0]) { 10 t1 = envelopes[j][0]; 11 envelopes[j][0] = envelopes[j+1][0]; 12 envelopes[j+1][0] = t1; 13 t2 = envelopes[j][1]; 14 envelopes[j][1] = envelopes[j+1][1]; 15 envelopes[j+1][1] = t2;16 }else if((envelopes[j][0]==envelopes[j+1][0])&&(envelopes[j][1]>envelopes[j+1][1])) { 17 t2 = envelopes[j][1]; 18 envelopes[j][1] = envelopes[j+1][1]; 19 envelopes[j+1][1] = t2; 20 } 21 } 22 } 23 int[]dp = new int[esize]; 24 Arrays.fill(dp,1); 25 for(int i = 1;i<esize;i++) { 26 for(int j = 0;j<i;j++) 27 if(envelopes[j][0]<envelopes[i][0] && envelopes[j][1]<envelopes[i][1])dp[i] = Math.max(dp[i],dp[j]+1); 28 ans = Math.max(ans, dp[i]); 29 } 30 return ans; 31 }