国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

青島網(wǎng)站設(shè)計微動力百家號推廣團隊

青島網(wǎng)站設(shè)計微動力百家號,推廣團隊,網(wǎng)站怎么做收費,購物網(wǎng)站策劃建設(shè)方案算法通關(guān)村第十九關(guān)——動態(tài)規(guī)劃高頻問題(白銀) 前言1 最少硬幣數(shù)2 最長連續(xù)遞增子序列3 最長遞增子序列4 完全平方數(shù)5 跳躍游戲6 解碼方法7 不同路徑 II 前言 摘自:代碼隨想錄 動態(tài)規(guī)劃五部曲: 確定dp數(shù)組(dp tabl…

算法通關(guān)村第十九關(guān)——動態(tài)規(guī)劃高頻問題(白銀)

    • 前言
    • 1 最少硬幣數(shù)
    • 2 最長連續(xù)遞增子序列
    • 3 最長遞增子序列
    • 4 完全平方數(shù)
    • 5 跳躍游戲
    • 6 解碼方法
    • 7 不同路徑 II

前言

摘自:代碼隨想錄

動態(tài)規(guī)劃五部曲:

  1. 確定dp數(shù)組(dp table)及其下標的含義
  2. 確定遞推公式
  3. 初始化dp數(shù)組
  4. 確定遍歷順序
  5. 舉例推導dp數(shù)組

1 最少硬幣數(shù)

leetcode 322. 零錢兌換

動規(guī)五部曲分析如下:

  1. 確定dp數(shù)組以及下標的含義

dp[j]:湊足總額為 j 所需錢幣的最少個數(shù)為dp[j]

  1. 確定遞推公式

湊足總額為j - coins[i]的最少個數(shù)為dp[j - coins[i]],

那么只需要加上一個錢幣coins[i]即dp[j - coins[i]] + 1就是dp[j](考慮coins[i])

所以dp[j] 要取所有 dp[j - coins[i]] + 1 中最小的。

遞推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);

  1. dp數(shù)組如何初始化

首先湊足總金額為0所需錢幣的個數(shù)一定是0,那么dp[0] = 0;

其他下標對應的數(shù)值呢?

考慮到遞推公式的特性,dp[j]必須初始化為一個最大的數(shù),否則就會在min(dp[j - coins[i]] + 1, dp[j])比較的過程中被初始值覆蓋。

所以下標非0的元素都是應該是最大值。

int[] dp = new int[amount + 1];
// 往數(shù)組dp里面填充某個數(shù),這里選擇amount+1,就是最大的值
Arrays.fill(dp, amount+1);
dp[0] = 0;
  1. 確定遍歷順序

有兩種方式:

第一種:外循環(huán)遍歷金額,內(nèi)循環(huán)遍歷硬幣面額。

第二種:外循環(huán)遍歷硬幣面面額,內(nèi)循環(huán)遍歷金額。

這兩種遍歷順序?qū)囊饬x如下:

  1. 外循環(huán)遍歷金額,內(nèi)循環(huán)遍歷硬幣面額:

    這種遍歷順序的意義是在計算找零過程中,我們首先考慮金額的變化,然后再考慮不同的硬幣面額。

    也就是說,我們固定一個金額,嘗試使用不同的硬幣面額來找零。這樣做的好處是可以利用之前已經(jīng)計算出來的金額的最少硬幣數(shù),快速得到當前金額的最優(yōu)解。由于金額是從小到大遞增的,所以我們在計算每個金額的最優(yōu)解時,可以利用前面較小金額的最優(yōu)解已經(jīng)被計算出來的特點。

// 遍歷金額
for (int i = 1; i <= amount; i++) {// 遍歷硬幣面額for (int j = 0; j < coins.length; j++) {if (coins[j] <= i) {dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);}}
}
  1. 外循環(huán)遍歷硬幣面額,內(nèi)循環(huán)遍歷金額:

    這種遍歷順序的意義是在計算找零過程中,我們首先考慮不同的硬幣面額,然后再考慮不同的金額。

    也就是說,我們固定一個硬幣面額,嘗試在不同的金額下進行找零。這樣做的好處是可以保證我們將所有可能的硬幣面額都考慮到,并且在計算每個金額的最優(yōu)解時,可以利用之前已經(jīng)計算出來的較小金額的最優(yōu)解。由于硬幣面額是從小到大遞增的,所以我們在計算每個金額的最優(yōu)解時,可以利用之前較小硬幣面額的最優(yōu)解已經(jīng)被計算出來的特點。

// 遍歷硬幣面額
for (int coin : coins){// 遍歷金額for (int i = 1; i <= amount; i++) {if(coin <= i){dp[i] = Math.min(dp[i], dp[i - coin] + 1);}}
}

全部代碼如下:

第一種:

class Solution {public int coinChange(int[] coins, int amount) {// 初始化dp數(shù)組int[] dp = new int[amount + 1];Arrays.fill(dp, amount + 1);dp[0] = 0;// 遍歷金額for (int i=1; i <= amount; i++) {// 遍歷硬幣面額for (int j=0; j < coins.length; j++){if(coins[j] <= i){dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);}}}return dp[amount] > amount ? -1 : dp[amount];}
}

第二種:

class Solution {public int coinChange(int[] coins, int amount) {// 初始化dp數(shù)組int[] dp = new int[amount + 1];Arrays.fill(dp, amount + 1);dp[0] = 0;// 遍歷硬幣面額for (int coin : coins){// 遍歷金額for (int i = 1; i <= amount; i++) {if(coin <= i){dp[i] = Math.min(dp[i], dp[i - coin] + 1);}}}return dp[amount] > amount ? -1 : dp[amount];}
}

2 最長連續(xù)遞增子序列

leetcode 674. 最長連續(xù)遞增序列

動規(guī)五部曲分析如下:

  1. 確定dp數(shù)組以及下標的含義

dp數(shù)組:表示以當前元素為結(jié)尾的最長連續(xù)遞增序列的長度。

dp[i]表示以nums[i]為結(jié)尾的最長連續(xù)遞增序列的長度。

  1. 確定遞推公式

如果nums[i] > nums[i-1],則dp[i] = dp[i-1] + 1;否則dp[i] = 1。

  1. dp數(shù)組如何初始化

我們將dp數(shù)組的所有元素初始化為1,因為每個元素都可以作為一個單獨的遞增序列。

  1. 確定遍歷順序

從第二個元素開始遍歷:

for(int i=0; i < nums.length; i++){if(i > 0 && nums[i] > nums[i-1]){dp[i] = dp[i-1] + 1;}else{dp[i] = 1;}
}
  1. 舉例說明

舉例說明:給定數(shù)組nums = [1, 3, 5, 4, 7]。

遍歷過程如下:

  • 對于nums[1] = 3,nums[0] = 1 < nums[1],所以dp[1] = dp[0] + 1 = 2。
  • 對于nums[2] = 5,nums[1] = 3 < nums[2],所以dp[2] = dp[1] + 1 = 3。
  • 對于nums[3] = 4,nums[2] = 5 > nums[3],所以dp[3] = 1。
  • 對于nums[4] = 7,nums[3] = 4 < nums[4],所以dp[4] = dp[3] + 1 = 2。

最終的最長連續(xù)遞增序列的長度為dp數(shù)組的最大值,即為3。

最后代碼如下:

class Solution {public int findLengthOfLCIS(int[] nums) {if (nums == null || nums.length == 0) {return 0;}int[] dp = new int[nums.length];dp[0] = 1;for(int i=1; i < nums.length; i++){if(nums[i] > nums[i-1]){dp[i] = dp[i-1] + 1;}else{dp[i] = 1;}}return Arrays.stream(dp).max().getAsInt();}
}

不是使用stream的方式:

class Solution {public int findLengthOfLCIS(int[] nums) {if (nums == null || nums.length == 0) {return 0;}int[] dp = new int[nums.length];dp[0] = 1;int maxLength = 1;for(int i=1; i < nums.length; i++){if(nums[i] > nums[i-1]){dp[i] = dp[i-1] + 1;}else{dp[i] = 1;}maxLength = Math.max(maxLength, dp[i]);}return maxLength;}
}

還可以得到dp[i],再遍歷一遍得到最大值,這就不寫了

3 最長遞增子序列

leetcode 300. 最長遞增子序列

  1. 確定dp數(shù)組(dp table)及其下標的含義:

    • dp數(shù)組:dp[i] 表示以第i個數(shù)字結(jié)尾的最長遞增子序列的長度。
    • 下標的含義:dp[i] 表示以第i個數(shù)字結(jié)尾的最長遞增子序列的長度。
  2. 確定遞推公式:

    • 如果nums[i] > nums[j],則:dp[i] = max(dp[i], dp[j] + 1)。

    為啥呢??

    這里的i和j表示數(shù)組nums的索引。具體來說,i表示當前遍歷到的元素的索引,而j表示在i之前的元素的索引。

    當我們遍歷到第i個元素時,我們需要尋找在i之前的元素中比nums[i]小的元素。這樣,我們就可以利用這個小于nums[i]的元素來構(gòu)成一個更長的遞增子序列。

    所以,當nums[i] > nums[j]時,表示nums[i]比nums[j]大,我們可以將以j結(jié)尾的最長遞增子序列的長度加1,然后與以i結(jié)尾的最長遞增子序列的長度進行比較,取較大的值作為以i結(jié)尾的最長遞增子序列的長度。也就是遞推公式中的 dp[i] = max(dp[i], dp[j] + 1)

  3. 初始化dp數(shù)組:

    • 初始時,dp數(shù)組中的每個元素都設(shè)為1,因為最短的遞增子序列長度為1。
  4. 確定遍歷順序:

    • 外層循環(huán)遍歷數(shù)組nums,從左到右依次計算dp[i]的值。
    • 內(nèi)層循環(huán)遍歷數(shù)組nums,從數(shù)組開始到i的位置,尋找前面的數(shù)字nums[j]是否小于nums[i],如果是,則根據(jù)遞推公式更新dp[i]的值。
  5. 舉例推導dp數(shù)組:

    如果nums[i] > nums[j],則dp[i] = max(dp[i], dp[j] + 1)。

    逐個元素計算dp[i]的值:

    • 當i = 1時,nums[i] = 9,此時沒有比9小的元素,所以以9結(jié)尾的最長遞增子序列長度仍為1。

    nums: 10 9 2 5 3 7 101 18
    dp: 1 1 1 1 1 1 1 1

    • 當i = 2時,nums[i] = 2,此時在2之前有9和10兩個元素,都比2大,所以以2結(jié)尾的最長遞增子序列長度仍為1。

    nums: 10 9 2 5 3 7 101 18
    dp: 1 1 1 1 1 1 1 1

    • 當i = 3時,nums[i] = 5,此時在5之前有2和9兩個元素,其中2比5小,所以以5結(jié)尾的最長遞增子序列長度為dp[2] + 1 = 2。

    nums: 10 9 2 5 3 7 101 18
    dp: 1 1 1 2 1 1 1 1

    • 當i = 4時,nums[i] = 3,此時在3之前有2和5兩個元素,其中2比3小,所以以3結(jié)尾的最長遞增子序列長度為dp[2] + 1 = 2。

    nums: 10 9 2 5 3 7 101 18
    dp: 1 1 1 2 2 1 1 1

后面略~~~~~~

完整代碼如下:

class Solution {public int lengthOfLIS(int[] nums) {if (nums == null || nums.length == 0) {return 0;}int n = nums.length;int[] dp = new int[n];dp[0] = 1; int result = 1; for (int i = 1; i < n; i++) {dp[i] = 1; for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) { dp[i] = Math.max(dp[i], dp[j] + 1); }}result = Math.max(result, dp[i]); }return result;}
}

4 完全平方數(shù)

leetcode 279. 完全平方數(shù)

動態(tài)規(guī)劃五部曲:

  1. 確定dp數(shù)組(dp table)及其下標的含義

**dp[i]:**表示數(shù)字i的最少完全平方數(shù)的個數(shù)。

  1. 確定遞推公式

對于數(shù)字 i 來說,我們需要遍歷所有小于等于 i 的完全平方數(shù) j( j 從 1 到 sqrt(i) ),然后將當前數(shù)字 i 減去 j 得到差值,即 i - j 。我們需要找到 dp[ i - j * j ] 的最小值,然后再加上1(表示當前完全平方數(shù) j ),即可得到dp[i]的值。

遞推公式為:dp[i] = Math.min(dp[i], dp[i - j * j] + 1),其中 j * j <= i。

  1. 初始化dp數(shù)組

Arrays.fill(dp, Integer.MAX_VALUE);

dp[0] = 0;

  1. 確定遍歷順序
// 遍歷dp數(shù)組
for (int i = 1; i <= n; i++) {// 遍歷小于等于i的完全平方數(shù)j*jfor (int j = 1; j * j <= i; j++) {// 更新dp[i]dp[i] = Math.min(dp[i], dp[i - j * j] + 1);}
}
  1. 舉例推導dp數(shù)組

略。。。

完整代碼:

class Solution {public int numSquares(int n) {// 定義dp數(shù)組int[] dp = new int[n + 1];// 初始化dp數(shù)組Arrays.fill(dp, n+1);dp[0] = 0;// 遍歷dp數(shù)組for (int i = 1; i <= n; i++) {// 遍歷小于等于i的完全平方數(shù)j*jfor (int j = 1; j * j <= i; j++) {// 更新dp[i]dp[i] = Math.min(dp[i], dp[i - j * j] + 1);}}return dp[n]; }
}

當然,這個代碼可以再優(yōu)化一下:(使用Math的api)
減少內(nèi)層循環(huán)的次數(shù):對于小于等于 i 的完全平方數(shù) j ,我們可以通過計算 i - j * j 的平方根得到 j 的最大值,并從最大值開始遍歷,這樣可以減少內(nèi)層循環(huán)的次數(shù)。

class Solution {public static int numSquares(int n) {// 定義dp數(shù)組int[] dp = new int[n + 1];// 初始化dp數(shù)組Arrays.fill(dp, n + 1);dp[0] = 0;// 遍歷dp數(shù)組for (int i = 1; i <= n; i++) {// 獲取當前數(shù)字i的最大完全平方數(shù)j*jint maxSquare = (int) Math.sqrt(i);// 遍歷完全平方數(shù)j*jfor (int j = maxSquare; j >= 1; j--) {// 更新dp[i]dp[i] = Math.min(dp[i], dp[i - j * j] + 1);}}return dp[n];}
}

5 跳躍游戲

leetcode 55. 跳躍游戲

動態(tài)規(guī)劃五部曲:

  1. 確定dp數(shù)組(dp table)及其下標的含義

dp[i]表示從起點位置到達位置i時能否跳躍到最后一個位置。

  1. 確定遞推公式

dp[i] = (dp[j] && nums[j] >= i - j),其中0 <= j < i

  1. 初始化dp數(shù)組

初始化dp數(shù)組所有位置為false。

  1. 確定遍歷順序

外層循環(huán)遍歷i從1到n-1,內(nèi)層循環(huán)遍歷j從0到i-1。

  1. 舉例推導dp數(shù)組

以數(shù)組nums = [2, 3, 1, 1, 4]為例進行推導:

初始狀態(tài):
dp = [false, false, false, false, false]

推導dp[1]:
dp[1] = (dp[0] && nums[0] >= 1 - 0) = (false && 2 >= 1) = false

推導dp[2]:
dp[2] = (dp[0] && nums[0] >= 2 - 0) || (dp[1] && nums[1] >= 2 - 1) = (false && 2 >= 2) || (false && 3 >= 2) = false

推導dp[3]:
dp[3] = (dp[0] && nums[0] >= 3 - 0) || (dp[1] && nums[1] >= 3 - 1) || (dp[2] && nums[2] >= 3 - 2) = (false && 2 >= 3) || (false && 3 >= 3) || (false && 1 >= 3) = false

完整代碼如下:

class Solution {public boolean canJump(int[] nums) {// 獲取數(shù)組長度int n = nums.length;// 定義dp數(shù)組boolean[] dp = new boolean[n];// 初始化dp數(shù)組dp[0] = true;// 遍歷dp數(shù)組for (int i = 1; i < n; i++) {// 內(nèi)層循環(huán)遍歷jfor (int j = 0; j < i; j++) {// 更新dp[i]dp[i] = dp[j] && nums[j] >= i - j;// 如果dp[i]為true,則跳出內(nèi)層循環(huán)if (dp[i]) {break;}}}return dp[n - 1];}
}

6 解碼方法

leetcode 91. 解碼方法

動態(tài)規(guī)劃五部曲:

  1. 確定dp數(shù)組(dp table)及其下標的含義

dp[i]表示從字符串的起始位置到第i個字符時的解碼方法總數(shù)。

  1. 確定遞推公式

對于dp數(shù)組中的每個位置i,我們需要考慮兩個情況:

  • 如果第i個字符能夠單獨解碼(即不為0),則dp[i] = dp[i-1],因為第i個字符自身可以作為一個解碼方法;
  • 如果第i個字符與前一個字符組成的兩位數(shù)能夠解碼(即與前一個字符組成的數(shù)字在1到26之間),則dp[i] += dp[i-2],因為組成的兩位數(shù)可以作為一個解碼方法。

則,遞推公式為:dp[i] = dp[i-1] + dp[i-2],其中0 <= i < n。

  1. 初始化dp數(shù)組

初始化dp數(shù)組的長度為n+1,初始值為0。

  1. 確定遍歷順序
for (int i = 1; i <= n; i++) {// 如果第i個字符能夠單獨解碼(即不為0)if (s.charAt(i - 1) != '0') {dp[i] += dp[i - 1];}// 如果第i個字符與前一個字符組成的兩位數(shù)能夠解碼(即與前一個字符組成的數(shù)字在1到26之間)if (i >= 2 && isValidEncoding(s.substring(i - 2, i))) {dp[i] += dp[i - 2];}
}
// 判斷字符串編碼是否在1到26之間
private static boolean isValidEncoding(String s) {if (s.charAt(0) == '0') {return false;}int num = Integer.parseInt(s);return num >= 1 && num <= 26;
}
  1. 舉例推導dp數(shù)組

以字符串s = "226"為例進行推導:

初始狀態(tài):
dp = [1, 0, 0, 0]

推導dp[1]:
如果第1個字符為2,能夠單獨解碼為"2",所以dp[1] = dp[0] = 1

推導dp[2]:
如果第2個字符為2,能夠單獨解碼為"2",所以dp[2] = dp[1] = 1
如果第1個字符與第2個字符組成的兩位數(shù)為26,能夠解碼為"26",所以dp[2] += dp[0],即dp[2] = dp[1] + dp[0] = 1 + 1 = 2

推導dp[3]:
如果第3個字符為6,能夠單獨解碼為"6",所以dp[3] = dp[2] = 2
如果第2個字符與第3個字符組成的兩位數(shù)為26,能夠解碼為"26",所以dp[3] += dp[1],即dp[3] = dp[2] + dp[1] = 2 + 1 = 3

最終結(jié)果:
dp = [1, 1, 2, 3]

完整代碼:

class Solution {public static int numDecodings(String s) {// 獲取字符串的長度int n = s.length();// 定義dp數(shù)組int[] dp = new int[n + 1];// 初始化dp數(shù)組dp[0] = 1;// 遍歷dp數(shù)組for (int i = 1; i <= n; i++) {// 如果第i個字符能夠單獨解碼(即不為0)if (s.charAt(i - 1) != '0') {dp[i] += dp[i - 1];}// 如果第i個字符與前一個字符組成的兩位數(shù)能夠解碼(即與前一個字符組成的數(shù)字在1到26之間)if (i >= 2 && isValidEncoding(s.substring(i - 2, i))) {dp[i] += dp[i - 2];}}return dp[n];}// 判斷字符串編碼是否在1到26之間private static boolean isValidEncoding(String s) {if (s.charAt(0) == '0') {return false;}int num = Integer.parseInt(s);return num >= 1 && num <= 26;}
}

不過可以簡化一下,就是比較難理解一點,意義一樣滴:

class Solution {public int numDecodings(String s) {int n = s.length();int[] f = new int[n + 1];f[0] = 1;for (int i = 1; i <= n; ++i) {if (s.charAt(i - 1) != '0') {f[i] += f[i - 1];}if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0') <= 26)) {f[i] += f[i - 2];}}return f[n];}
}

7 不同路徑 II

leetcode 63. 不同路徑 II

這題就是62的改版,所以復雜了很多,還是建議看代碼隨想錄:動態(tài)規(guī)劃——不同路徑

動規(guī)五部曲:

  1. 確定dp數(shù)組(dp table)以及下標的含義

**dp[i] [j] :**表示從(0 ,0)出發(fā),到(i, j) 有dp[i] [j]條不同的路徑。

  1. 確定遞推公式

遞推公式和62.不同路徑一樣,dp[i] [j] = dp[i - 1] [j] + dp[i] [j - 1]。

但這里需要注意一點,因為有了障礙,(i, j)如果就是障礙的話應該就保持初始狀態(tài)(初始狀態(tài)為0)。

所以代碼為:

if (obstacleGrid[i][j] == 0) { // 當(i, j)沒有障礙的時候,再推導dp[i][j]dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
  1. dp數(shù)組如何初始化

因為從(0, 0)的位置到(i, 0)的路徑只有一條,所以dp[i] [0]一定為1,dp[0] [j]也同理。

但如果(i, 0) 這條邊有了障礙之后,障礙之后(包括障礙)都是走不到的位置了,所以障礙之后的dp[i] [0]應該還是初始值0。

如圖:

image-20230910161750355

下標(0, j)的初始化情況同理。

所以本題初始化代碼為:

int[][] dp = new int[m][n];
for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {dp[i][0] = 1;
}
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {dp[0][j] = 1;
}

注意代碼里for循環(huán)的終止條件,一旦遇到obstacleGrid[i] [0] == 1的情況就停止dp[i] [0]的賦值1的操作,dp[0] [j]同理

  1. 確定遍歷順序

從遞歸公式dp[i] [j] = dp [i - 1] [j] + dp[i] [j - 1] 中可以看出,一定是從左到右一層一層遍歷,這樣保證推導dp[i] [j]的時候,dp[i - 1] [j] 和 dp[i] [j - 1]一定是有數(shù)值。

代碼如下:

for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {dp[i][j] = (obstacleGrid[i][j] == 0) ? dp[i - 1][j] + dp[i][j - 1] : 0;}
}
  1. 舉例推導dp數(shù)組

image-20230910162011436

完整代碼如下:

class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length;int[][] dp = new int[m][n];//如果在起點或終點出現(xiàn)了障礙,直接返回0if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) {return 0;}for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {dp[i][0] = 1;}for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {dp[0][j] = 1;}for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {dp[i][j] = (obstacleGrid[i][j] == 0) ? dp[i - 1][j] + dp[i][j - 1] : 0;}}return dp[m - 1][n - 1];}
}

至于118,119我個人覺得并不合適使用動態(tài)規(guī)劃的方式,所以就不寫了,over~~

http://m.aloenet.com.cn/news/31938.html

相關(guān)文章:

  • 蘋果手機允許網(wǎng)站設(shè)置百度廣告聯(lián)盟app下載官網(wǎng)
  • 有什么軟件做短視頻網(wǎng)站免費網(wǎng)站生成器
  • 掃描二維碼進入公司網(wǎng)站怎樣做原創(chuàng)文章代寫平臺
  • 申請微官網(wǎng)的網(wǎng)站百度關(guān)鍵詞首頁排名怎么上
  • asp做網(wǎng)站搜索免費seo教程分享
  • phpcmsv9手機網(wǎng)站模板建設(shè)網(wǎng)站的步驟
  • 西安建委官網(wǎng)太原seo網(wǎng)站優(yōu)化
  • 龍溪營銷型網(wǎng)站制作好123上網(wǎng)主頁
  • 微網(wǎng)站怎么做的好網(wǎng)站優(yōu)化推廣公司
  • 做海報可以在哪些網(wǎng)站下載素材萊陽seo外包
  • 廣東品牌網(wǎng)站設(shè)計專家百度云網(wǎng)盤網(wǎng)頁版
  • 設(shè)計大神云集的網(wǎng)站是網(wǎng)絡(luò)推廣方法怎么樣
  • 怎樣增加網(wǎng)站收錄量谷歌瀏覽器引擎入口
  • 展示類網(wǎng)站建設(shè)qianhu微建站
  • 點網(wǎng)站出圖片怎么做網(wǎng)站開發(fā)培訓
  • 沈陽網(wǎng)站建設(shè)培訓學校怎么建網(wǎng)站教程圖解
  • 大型網(wǎng)站seo方案長沙網(wǎng)站推廣seo
  • 百度上做網(wǎng)站免費嗎品牌運營策劃方案
  • 邢臺人才網(wǎng)官網(wǎng)首頁下載優(yōu)化大師
  • dw網(wǎng)站建設(shè)流程游戲搜索風云榜
  • dreamwave cs6建設(shè)php網(wǎng)站十大成功營銷策劃案例
  • 保定網(wǎng)站排名優(yōu)化直通車關(guān)鍵詞優(yōu)化
  • wordpress 送錢啦濟南網(wǎng)站優(yōu)化排名推廣
  • 鹽城做百度網(wǎng)站百度推廣服務費3000元
  • 哪里有網(wǎng)站開發(fā)設(shè)計文章優(yōu)化關(guān)鍵詞排名
  • 做好網(wǎng)站建設(shè)通知seo行業(yè)崗位
  • 單頁面組合網(wǎng)站seo關(guān)鍵詞布局技巧
  • 公司官網(wǎng)站怎么搞南平seo
  • 找人做網(wǎng)站設(shè)計 哪個平臺可以找萬能的搜索引擎
  • 如何在本地搭建網(wǎng)站什么網(wǎng)站百度收錄快