藍橋杯備賽 (LintCode上刷的第一題)
749 約翰的後花園
準備藍橋杯大賽已經有很長一段時間了。一直在努力的學習算法,不過之前都是看別人的思路和代碼,從來沒有自己獨自一個人從頭到尾的做完一道題。所以即使今天花了三個小時,做完了這道難度係數最簡單的動態規劃的題目。仍然仍然非常非常有成就感!!!第一步的跨越是最難的,也是最有成就感的!!!
問題描述
約翰想在他家後面的空地上建一個後花園,現在有兩種磚,一種3 dm的高度,7 dm的高度。約翰想圍成x dm的牆。如果約翰能做到,輸出YES,否則輸出NO。
樣例輸出
-
給出 x = 10,返回YES。
解釋:
x = 3 + 7 : 即需要1匹3 dm高度的磚和1匹7 dm 高度的磚。 -
給出 x = 5,返回 NO。
解釋:
不能用高度爲3 dm的磚和高度爲7 dm的磚砌成 5 dm的牆。 -
給出 x = 13,返回YES。
解釋:
x = 2 * 3 + 7 : 即需要2匹3 dm高度的磚和1匹7 dm 高度的磚。
問題分析
說實話,作爲初學者,也不怎麼能看出什麼題採用什麼樣的方法。由於此時狂刷動態規劃的算法,所以現在進入了動態規劃系列問題的刷題階段。我在做這道題的時候,參考了換硬幣,換紙幣這類相似的題目。整個過程下來,三個小時,流程邏輯思路都很清楚了!
因爲借鑑以上兩個題目,因此創建邏輯數組dp[i][aim]表示能否採用i種磚砌成高度爲aim的牆。
java實現代碼
package DP;
import java.util.Scanner;
public class JohnGarden1110 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 輸入牆的高度
int aim = sc.nextInt();
// 一維數組保存磚的高度
int[] brick = new int[2];
brick[0] = 3;
brick[1] = 7;
// dp[i][j]表示用i種磚砌成j高度時一共需要用多少塊磚
int[][] dp = new int[2][aim + 1];
// 當只採用3分米的磚時,只能組成3的倍數的高度
for (int i = 0; i * brick[0] <= aim; i++) {
dp[0][i * brick[0]] = 1;
}
if (aim >= 3 && aim <= 1000) {
// 遍歷每一個小於等於aim的值
for (int j = 3; j < aim; j = j + 3) {
// 當採用k塊7分米的磚時,對k的值從0開始遍歷
for (int k = 1; j + k * brick[1] <= aim; k++) {
// 在採用k塊3分米的磚的情況下,再採用7分米的磚,如果能砌成目標高度
if (j + k * brick[1] == aim) {
// System.out.println("Yes");
// 將對應元素值置爲1
dp[1][j + k * brick[1]] = 1;
System.out.println("j" + j + " k" + k + " sum" + dp[1][j + k * brick[1]]);
}
}
}
}
// 根據dp[1][aim]和dp[0][aim]的值判斷,爲1表示可以砌成目標高度,否則不能
if (dp[1][aim] == 1 || dp[0][aim] == 1) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
堅持下來的每一天,都離自己的目標更近一些!有夢想的人在閃閃發亮!