色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

回溯算法技巧分析

jf_78858299 ? 來(lái)源:labuladong ? 作者:labuladong ? 2023-04-19 11:00 ? 次閱讀

解決一個(gè)回溯問(wèn)題,實(shí)際上就是一個(gè)決策樹(shù)的遍歷過(guò)程 。你只需要思考 3 個(gè)問(wèn)題:

1、 路徑 :也就是已經(jīng)做出的選擇。

2、選擇列表 :也就是你當(dāng)前可以做的選擇。

3、結(jié)束條件 :也就是到達(dá)決策樹(shù)底層,無(wú)法再做選擇的條件。

如果你不理解這三個(gè)詞語(yǔ)的解釋?zhuān)瑳](méi)關(guān)系,我們后面會(huì)用「全排列」和「N 皇后問(wèn)題」這兩個(gè)經(jīng)典的回溯算法問(wèn)題來(lái)幫你理解這些詞語(yǔ)是什么意思,現(xiàn)在你先留著印象。

代碼方面,回溯算法的框架:

result = []
def backtrack(路徑, 選擇列表):
    if 滿(mǎn)足結(jié)束條件:
        result.add(路徑)
        return

    for 選擇 in 選擇列表:
        做選擇
        backtrack(路徑, 選擇列表)
        撤銷(xiāo)選擇

其核心就是 for 循環(huán)里面的遞歸,在遞歸調(diào)用之前「做選擇」,在遞歸調(diào)用之后「撤銷(xiāo)選擇」 ,特別簡(jiǎn)單。

什么叫做選擇和撤銷(xiāo)選擇呢,這個(gè)框架的底層原理是什么呢?下面我們就通過(guò)「全排列」這個(gè)問(wèn)題來(lái)解開(kāi)之前的疑惑,詳細(xì)探究一下其中的奧妙!

一、全排列問(wèn)題

我們?cè)诟咧械臅r(shí)候就做過(guò)排列組合的數(shù)學(xué)題,我們也知道n個(gè)不重復(fù)的數(shù),全排列共有 n! 個(gè)。

PS: 為了簡(jiǎn)單清晰起見(jiàn),我們這次討論的全排列問(wèn)題不包含重復(fù)的數(shù)字

那么我們當(dāng)時(shí)是怎么窮舉全排列的呢?比方說(shuō)給三個(gè)數(shù)[1,2,3],你肯定不會(huì)無(wú)規(guī)律地亂窮舉,一般是這樣:

先固定第一位為 1,然后第二位可以是 2,那么第三位只能是 3;然后可以把第二位變成 3,第三位就只能是 2 了;然后就只能變化第一位,變成 2,然后再窮舉后兩位……

其實(shí)這就是回溯算法,我們高中無(wú)師自通就會(huì)用,或者有的同學(xué)直接畫(huà)出如下這棵回溯樹(shù):

圖片

只要從根遍歷這棵樹(shù),記錄路徑上的數(shù)字,其實(shí)就是所有的全排列。 我們不妨把這棵樹(shù)稱(chēng)為回溯算法的「決策樹(shù)」

為啥說(shuō)這是決策樹(shù)呢,因?yàn)槟阍诿總€(gè)節(jié)點(diǎn)上其實(shí)都在做決策 。比如說(shuō)你站在下圖的紅色節(jié)點(diǎn)上:

圖片

你現(xiàn)在就在做決策,可以選擇 1 那條樹(shù)枝,也可以選擇 3 那條樹(shù)枝。為啥只能在 1 和 3 之中選擇呢?因?yàn)?2 這個(gè)樹(shù)枝在你身后,這個(gè)選擇你之前做過(guò)了,而全排列是不允許重復(fù)使用數(shù)字的。

現(xiàn)在可以解答開(kāi)頭的幾個(gè)名詞:[2]就是「路徑」,記錄你已經(jīng)做過(guò)的選擇;[1,3]就是「選擇列表」,表示你當(dāng)前可以做出的選擇;「結(jié)束條件」就是遍歷到樹(shù)的底層,在這里就是選擇列表為空的時(shí)候

如果明白了這幾個(gè)名詞,可以把「路徑」和「選擇 列表 」作為決策樹(shù)上每個(gè)節(jié)點(diǎn)的屬性 ,比如下圖列出了幾個(gè)節(jié)點(diǎn)的屬性:

圖片

我們定義的backtrack函數(shù)其實(shí)就像一個(gè)指針,在這棵樹(shù)上游走,同時(shí)要正確維護(hù)每個(gè)節(jié)點(diǎn)的屬性,每當(dāng)走到樹(shù)的底層,其「路徑」就是一個(gè)全排列

再進(jìn)一步,如何遍歷一棵樹(shù)?這個(gè)應(yīng)該不難吧。回憶一下之前 [學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)的框架思維]寫(xiě)過(guò),各種搜索問(wèn)題其實(shí)都是樹(shù)的遍歷問(wèn)題,而多叉樹(shù)的遍歷框架就是這樣:

void traverse(TreeNode root) {
    for (TreeNode child : root.childern)
        // 前序遍歷需要的操作
        traverse(child);
        // 后序遍歷需要的操作
}

而所謂的前序遍歷和后序遍歷,他們只是兩個(gè)很有用的時(shí)間點(diǎn),我給你畫(huà)張圖你就明白了:

圖片

前序遍歷的代碼在進(jìn)入某一個(gè)節(jié)點(diǎn)之前的那個(gè)時(shí)間點(diǎn)執(zhí)行,后序遍歷代碼在離開(kāi)某個(gè)節(jié)點(diǎn)之后的那個(gè)時(shí)間點(diǎn)執(zhí)行

回想我們剛才說(shuō)的,「路徑」和「選擇」是每個(gè)節(jié)點(diǎn)的屬性,函數(shù)在樹(shù)上游走要正確維護(hù)節(jié)點(diǎn)的屬性,那么就要在這兩個(gè)特殊時(shí)間點(diǎn)搞點(diǎn)動(dòng)作:

圖片

現(xiàn)在,你是否理解了回溯算法的這段核心框架?

for 選擇 in 選擇列表:
    # 做選擇
    將該選擇從選擇列表移除
    路徑.add(選擇)
    backtrack(路徑, 選擇列表)
    # 撤銷(xiāo)選擇
    路徑.remove(選擇)
    將該選擇再加入選擇列表

我們只要在遞歸之前做出選擇,在遞歸之后撤銷(xiāo)剛才的選擇 ,就能正確得到每個(gè)節(jié)點(diǎn)的選擇列表和路徑。

下面,直接看全排列代碼:

List<List<Integer>> res = new LinkedList<>();

/* 主函數(shù),輸入一組不重復(fù)的數(shù)字,返回它們的全排列 */
List<List<Integer>> permute(int[] nums) {
    // 記錄「路徑」
    LinkedList<Integer> track = new LinkedList<>();
    backtrack(nums, track);
    return res;
}

// 路徑:記錄在 track 中
// 選擇列表:nums 中不存在于 track 的那些元素
// 結(jié)束條件:nums 中的元素全都在 track 中出現(xiàn)
void backtrack(int[] nums, LinkedList<Integer> track) {
    // 觸發(fā)結(jié)束條件
    if (track.size() == nums.length) {
        res.add(new LinkedList(track));
        return;
    }

    for (int i = 0; i < nums.length; i++) {
        // 排除不合法的選擇
        if (track.contains(nums[i]))
            continue;
        // 做選擇
        track.add(nums[i]);
        // 進(jìn)入下一層決策樹(shù)
        backtrack(nums, track);
        // 取消選擇
        track.removeLast();
    }
}

我們這里稍微做了些變通,沒(méi)有顯式記錄「選擇列表」,而是通過(guò)numstrack推導(dǎo)出當(dāng)前的選擇列表

至此,我們就通過(guò)全排列問(wèn)題詳解了回溯算法的底層原理。當(dāng)然,這個(gè)算法解決全排列不是很高效,因?yàn)閷?duì)鏈表使用contains方法需要 O(N) 的時(shí)間復(fù)雜度。有更好的方法通過(guò)交換元素達(dá)到目的,但是難理解一些,這里就不寫(xiě)了,有興趣可以自行搜索一下。

但是必須說(shuō)明的是,不管怎么優(yōu)化,都符合回溯框架,而且時(shí)間復(fù)雜度都不可能低于 O(N!),因?yàn)楦F舉整棵決策樹(shù)是無(wú)法避免的。 這也是回溯算法的一個(gè)特點(diǎn),不像動(dòng)態(tài)規(guī)劃存在重疊子問(wèn)題可以?xún)?yōu)化,回溯算法就是純暴力窮舉,復(fù)雜度一般都很高

明白了全排列問(wèn)題,就可以直接套回溯算法框架了,下面簡(jiǎn)單看看 N 皇后問(wèn)題。

二、N 皇后問(wèn)題

這個(gè)問(wèn)題很經(jīng)典了,簡(jiǎn)單解釋一下:給你一個(gè) N×N 的棋盤(pán),讓你放置 N 個(gè)皇后,使得它們不能互相攻擊。

PS:皇后可以攻擊同一行、同一列、左上左下右上右下四個(gè)方向的任意單位。

這是 N = 8 的一種放置方法:

圖片

圖片來(lái)自 LeetCode

這個(gè)問(wèn)題本質(zhì)上跟全排列問(wèn)題差不多,決策樹(shù)的每一層表示棋盤(pán)上的每一行;每個(gè)節(jié)點(diǎn)可以做出的選擇是,在該行的任意一列放置一個(gè)皇后。

直接套用框架:

vector

這部分主要代碼,跟全排列問(wèn)題差不多。isValid函數(shù)的實(shí)現(xiàn)也很簡(jiǎn)單:

/* 是否可以在 board[row][col] 放置皇后? */
bool isValid(vector {
    int n = board.size();
    // 檢查列是否有皇后互相沖突
    for (int i = 0; i < n; i++) {
        if (board[i][col] == 'Q')
            return false;
    }
    // 檢查右上方是否有皇后互相沖突
    for (int i = row - 1, j = col + 1; 
            i >= 0 && j < n; i--, j++) {
        if (board[i][j] == 'Q')
            return false;
    }
    // 檢查左上方是否有皇后互相沖突
    for (int i = row - 1, j = col - 1;
            i >= 0 && j >= 0; i--, j--) {
        if (board[i][j] == 'Q')
            return false;
    }
    return true;
}

函數(shù)backtrack依然像個(gè)在決策樹(shù)上游走的指針,每個(gè)節(jié)點(diǎn)就表示在board[row][col]上放置皇后,通過(guò)isValid函數(shù)可以將不符合條件的情況剪枝

如果直接給你這么一大段解法代碼,可能是懵逼的。但是現(xiàn)在明白了回溯算法的框架套路,還有啥難理解的呢?無(wú)非是改改做選擇的方式,排除不合法選擇的方式而已,只要框架存于心,你面對(duì)的只剩下小問(wèn)題了。

當(dāng)N = 8時(shí),就是八皇后問(wèn)題,數(shù)學(xué)大佬高斯窮盡一生都沒(méi)有數(shù)清楚八皇后問(wèn)題到底有幾種可能的放置方法,但是我們的算法只需要一秒就可以算出來(lái)所有可能的結(jié)果。

不過(guò)真的不怪高斯。這個(gè)問(wèn)題的復(fù)雜度確實(shí)非常高,看看我們的決策樹(shù),雖然有isValid函數(shù)剪枝,但是最壞時(shí)間復(fù)雜度仍然是 O(N^(N+1)),而且無(wú)法優(yōu)化。如果N = 10的時(shí)候,計(jì)算就已經(jīng)很耗時(shí)了。

有的時(shí)候,我們并不想得到所有合法的答案,只想要一個(gè)答案,怎么辦呢 ?比如解數(shù)獨(dú)的算法,找所有解法復(fù)雜度太高,只要找到一種解法就可以。

其實(shí)特別簡(jiǎn)單,只要稍微修改一下回溯算法的代碼即可:

// 函數(shù)找到一個(gè)答案后就返回 true
bool backtrack(vector {
    // 觸發(fā)結(jié)束條件
    if (row == board.size()) {
        res.push_back(board);
        return true;
    }
    ...
    for (int col = 0; col < n; col++) {
        ...
        board[row][col] = 'Q';

        if (backtrack(board, row + 1))
            return true;

        board[row][col] = '.';
    }

    return false;
}

這樣修改后,只要找到一個(gè)答案,for 循環(huán)的后續(xù)遞歸窮舉都會(huì)被阻斷。也許你可以在 N 皇后問(wèn)題的代碼框架上,稍加修改,寫(xiě)一個(gè)解數(shù)獨(dú)的算法?

三、最后總結(jié)

回溯算法就是個(gè)多叉樹(shù)的遍歷問(wèn)題,關(guān)鍵就是在前序遍歷和后序遍歷的位置做一些操作,算法框架如下:

def backtrack(...):
    for 選擇 in 選擇列表:
        做選擇
        backtrack(...)
        撤銷(xiāo)選擇

寫(xiě)backtrack函數(shù)時(shí),需要維護(hù)走過(guò)的「路徑」和當(dāng)前可以做的「選擇列表」,當(dāng)觸發(fā)「結(jié)束條件」時(shí),將「路徑」記入結(jié)果集

其實(shí)想想看,回溯算法和動(dòng)態(tài)規(guī)劃是不是有點(diǎn)像呢?我們?cè)趧?dòng)態(tài)規(guī)劃系列文章中多次強(qiáng)調(diào),動(dòng)態(tài)規(guī)劃的三個(gè)需要明確的點(diǎn)就是「狀態(tài)」「選擇」和「base case」,是不是就對(duì)應(yīng)著走過(guò)的「路徑」,當(dāng)前的「選擇列表」和「結(jié)束條件」?

某種程度上說(shuō),動(dòng)態(tài)規(guī)劃的暴力求解階段就是回溯算法。只是有的問(wèn)題具有重疊子問(wèn)題性質(zhì),可以用 dp table 或者備忘錄優(yōu)化,將遞歸樹(shù)大幅剪枝,這就變成了動(dòng)態(tài)規(guī)劃。而今天的兩個(gè)問(wèn)題,都沒(méi)有重疊子問(wèn)題,也就是回溯算法問(wèn)題了,復(fù)雜度非常高是不可避免的。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 回溯算法
    +關(guān)注

    關(guān)注

    0

    文章

    10

    瀏覽量

    6619
  • for循環(huán)
    +關(guān)注

    關(guān)注

    0

    文章

    61

    瀏覽量

    2503
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    回溯經(jīng)典 (五皇后問(wèn)題) (算法)

    5皇后問(wèn)題:在8*8的國(guó)際象棋棋盤(pán)上,放5個(gè)皇后,使它們控制整個(gè)棋盤(pán),即在任何一格放一個(gè)棋子,都會(huì)馬上被吃掉。下面介紹回溯解法定義一個(gè)表示點(diǎn)的數(shù)據(jù)結(jié)構(gòu): struct Pt {Int x,y
    發(fā)表于 08-16 14:56

    算法設(shè)計(jì)與分析王曉東

    算法設(shè)計(jì)與分析王曉東編著主要內(nèi)容介紹第1章 算法引論第2章 遞歸與分治策略第3章 動(dòng)態(tài)規(guī)劃第4章 貪心算法第5章 
    發(fā)表于 11-25 23:50 ?0次下載
    <b class='flag-5'>算法</b>設(shè)計(jì)與<b class='flag-5'>分析</b>王曉東

    一種無(wú)回溯的最長(zhǎng)前綴匹配搜索算法

    研究網(wǎng)絡(luò)處理器中的搜索算法,提出一種基于Patricia樹(shù)的無(wú)回溯搜索算法,并進(jìn)行仿真和評(píng)估分析。該算法被用于中科院計(jì)算所的網(wǎng)絡(luò)處理器的搜索
    發(fā)表于 04-22 09:41 ?18次下載

    基于回溯的RFID防沖撞算法

    針對(duì)RFID 系統(tǒng)中常見(jiàn)的沖撞問(wèn)題,提出一種基于回溯的精簡(jiǎn)結(jié)點(diǎn)二叉樹(shù)搜索防沖撞算法,在分析二進(jìn)制搜索和動(dòng)態(tài)二進(jìn)制算法性能的基礎(chǔ)上,得出了提高效率的關(guān)鍵所在,在達(dá)到
    發(fā)表于 12-18 12:06 ?18次下載

    模板方法模式在回溯算法中的應(yīng)用

    描述了模板方法模式及回溯算法的模板方法模式的Java 語(yǔ)言實(shí)現(xiàn),該實(shí)現(xiàn)使得回溯算法的實(shí)現(xiàn)達(dá)到了可擴(kuò)展性、靈活性和可插入性三個(gè)目標(biāo),提高了算法
    發(fā)表于 01-15 16:48 ?20次下載

    模板方法模式在回溯算法中的應(yīng)用

    描述了模板方法模式及回溯算法的模板方法模式的Java 語(yǔ)言實(shí)現(xiàn),該實(shí)現(xiàn)使得回溯算法的實(shí)現(xiàn)達(dá)到了可擴(kuò)展性、靈活性和可插入性三個(gè)目標(biāo),提高了算法
    發(fā)表于 01-15 16:51 ?0次下載

    求組合問(wèn)題的不同算法比較分析

    介紹了遞歸法與回溯法的一般思想,分析了用遞歸法與回溯法求解組合問(wèn)題,還對(duì)求解問(wèn)題的復(fù)雜度以及優(yōu)缺點(diǎn)進(jìn)行了分析比較。
    發(fā)表于 07-01 18:29 ?22次下載

    Viterbi譯碼器回溯算法實(shí)現(xiàn)

    該文介紹了兩種Viterbi 譯碼器回溯譯碼算法,通過(guò)對(duì)這兩種算法硬件實(shí)現(xiàn)結(jié)構(gòu)上的優(yōu)化,給出了這兩種算法的FPGA 實(shí)現(xiàn)方法,比較了兩種實(shí)現(xiàn)方法的優(yōu)缺點(diǎn)。最后將其應(yīng)用在實(shí)際的Viter
    發(fā)表于 05-28 15:18 ?33次下載
    Viterbi譯碼器<b class='flag-5'>回溯</b><b class='flag-5'>算法</b>實(shí)現(xiàn)

    基于回溯搜索優(yōu)化算法改進(jìn)矩陣填充的指紋庫(kù)構(gòu)建

    針對(duì)基于信號(hào)強(qiáng)度指示( RSSI)的位置指紋定位過(guò)程中用于其離線位置指紋庫(kù)構(gòu)建的全采法采集工作量較大、位置指紋庫(kù)構(gòu)建效率較低、而插值法通常精度有限等問(wèn)題,提出一種基于回溯搜索優(yōu)化算法改進(jìn)奇異值閾值
    發(fā)表于 11-30 14:33 ?3次下載

    五大常用算法回溯

    回溯算法實(shí)際上一個(gè)類(lèi)似枚舉的搜索嘗試過(guò)程,主要是在搜索嘗試過(guò)程中尋找問(wèn)題的解,當(dāng)發(fā)現(xiàn)已不滿(mǎn)足求解條件時(shí),就“回溯”返回,嘗試別的路徑。
    的頭像 發(fā)表于 05-02 16:50 ?5968次閱讀
    五大常用<b class='flag-5'>算法</b>之<b class='flag-5'>回溯</b>法

    回溯的共軛梯度迭代硬閾值算法如何解決迭代次數(shù)多重構(gòu)時(shí)間長(zhǎng)的問(wèn)題

    針對(duì)基于回溯的迭代硬閾值算法( BIHT)迭代次數(shù)多、重構(gòu)時(shí)間長(zhǎng)的問(wèn)題,提出一種基于回溯的共軛梯度迭代硬閾值算法( BCGIHT)。首先,在每次迭代中采用
    發(fā)表于 12-20 14:08 ?0次下載
    <b class='flag-5'>回溯</b>的共軛梯度迭代硬閾值<b class='flag-5'>算法</b>如何解決迭代次數(shù)多重構(gòu)時(shí)間長(zhǎng)的問(wèn)題

    C語(yǔ)言重解經(jīng)典回溯算法案例

    迷宮問(wèn)題是一道經(jīng)典的回溯算法問(wèn)題,給定一個(gè)迷宮矩陣,矩陣中的1表示障礙,0表示可走通路,給定迷宮入口出口,要求尋找從入口穿過(guò)迷宮到達(dá)出口的所有路徑,有則輸出,無(wú)則給出提示。
    的頭像 發(fā)表于 01-29 11:24 ?4921次閱讀
    C語(yǔ)言重解經(jīng)典<b class='flag-5'>回溯</b><b class='flag-5'>算法</b>案例

    關(guān)于回溯算法的介紹與運(yùn)用

    本文就來(lái)看一道非常經(jīng)典的回溯算法問(wèn)題,子集劃分問(wèn)題,可以幫你更深刻理解回溯算法的思維,得心應(yīng)手地寫(xiě)出回溯函數(shù)。
    的頭像 發(fā)表于 03-25 13:42 ?1656次閱讀

    算法時(shí)空復(fù)雜度分析實(shí)用指南(上)

    本文會(huì)篇幅較長(zhǎng),會(huì)涵蓋如下幾點(diǎn): 1、Big O 表示法的幾個(gè)基本特點(diǎn)。 2、非遞歸算法中的時(shí)間復(fù)雜度分析。 3、數(shù)據(jù)結(jié)構(gòu) API 的效率衡量方法(攤還分析)。 4、遞歸
    的頭像 發(fā)表于 04-19 10:34 ?839次閱讀
    <b class='flag-5'>算法</b>時(shí)空復(fù)雜度<b class='flag-5'>分析</b>實(shí)用指南(上)

    算法時(shí)空復(fù)雜度分析實(shí)用指南(下)

    Big O 表示法的幾個(gè)基本特點(diǎn)。 2、非遞歸算法中的時(shí)間復(fù)雜度分析。 3、數(shù)據(jù)結(jié)構(gòu) API 的效率衡量方法(攤還分析)。 4、遞歸算法的時(shí)間/空間復(fù)雜度的
    的頭像 發(fā)表于 04-19 10:35 ?702次閱讀
    <b class='flag-5'>算法</b>時(shí)空復(fù)雜度<b class='flag-5'>分析</b>實(shí)用指南(下)
    主站蜘蛛池模板: 黄片在线观看| 亚洲中文久久精品AV无码| 日本久久不射| 神马电影dy888午夜我不卡| 亚洲国产第一区二区三区| 在线亚洲国产日韩欧洲专区| AV72啪啪网站| 国产精品久免费的黄网站| 国产 高清 无码 中文| 黑吊大战白女出浆| 么公在浴室了我的奶| 色播播影院| 在线国产三级| 国产 日韩 欧美 高清 亚洲 | 亚洲精品久久久无码一区二区| 中文字幕人成人乱码亚洲影视| 成人在线免费视频播放| 九九热视频免费观看| 日本大片免a费观看视频| 亚洲综合AV色婷婷五月蜜臀| 扒开老师大腿猛进AAA片软件| 黄色a三级免费看| 日日干夜夜爱| 最近中文字幕2019免费版| 国产成人精品视频播放| 毛片免费观看的视频在线| 性饥渴姓交HDSEX| JAVAPARSER丰满白老师| 好爽别插了无码视频| 日本又黄又裸一级大黄裸片| 在线观看中文字幕码2021不用下载| 俄罗斯9一14 young处| 恋夜秀场1234手机视频在线观看| 脱jk裙的美女露小内内无遮挡| 16女下面流水不遮图免费观看| 国产精品三级在线观看 | 久久6699精品国产人妻| 日日噜噜夜夜爽爽| 2022国产麻豆剧传媒剧情| 国产色精品VR一区二区| 全球真实小U女视频合集|