DP專題總結(jié)

1.動(dòng)態(tài)規(guī)劃

一個(gè)問(wèn)題如果具有重復(fù)子問(wèn)題,那么可以用動(dòng)態(tài)規(guī)劃求解绪励,從而減少大量重復(fù)計(jì)算。

2.數(shù)塔問(wèn)題

image.png

問(wèn):從第一層走到最后一層所有路徑上的數(shù)字相加后最大和是多少却盘?
令dp[i][j]表示第i層第j個(gè)數(shù)字當(dāng)前的最大和拴疤,則狀態(tài)轉(zhuǎn)移方程:

邊界:,使用choice[i][j]數(shù)組記錄每一個(gè)節(jié)點(diǎn)是由下層哪個(gè)節(jié)點(diǎn)得到的字管,從而回溯構(gòu)造結(jié)果
程序代碼:

#include<cstdio>
#include<algorithm>

using namespace std;

const int maxn = 100;
int numTower[maxn][maxn];
int dp[maxn][maxn];    
int choice[maxn][maxn] = {0};

int main()
{
    int n;

    scanf("%d",&n); //2?êy
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            scanf("%d",&numTower[i][j]);
        }
    }


    //±???£o×?oóò?2?μ?×?ó??μμèóúμ±?°êy
    for(int i=0;i<n;i++)
        dp[n-1][i] = numTower[n-1][i];

    //óé???áé?£?×′ì?×aò?·?3ì£o dp[i][j] = maxn(dp[i+1][j] + dp[i+1][j+1]) + numTower[i][j]
    for(int i=n-2;i>=0;i--)
        for(int j=0;j<=i;j++){
            if(dp[i+1][j] >= dp[i+1][j+1]){
                dp[i][j] = dp[i+1][j] + numTower[i][j];
                choice[i][j] = 1;
            }
            else{
                dp[i][j] = dp[i+1][j+1] + numTower[i][j];
                choice[i][j] = 2;
            }
        }
    printf("%d\n",dp[0][0]);
    int j = 0;
    for (int i = 0; i < n; ++i)
    {
        printf("%d",numTower[i][j] );
        if (choice[i][j] == 2)
        {
            j++;
        }
        if(i != n-1)
            printf(" ");
    }
}

3.最大連續(xù)子序列和

問(wèn)題:給定K個(gè)整數(shù)的序列{ N1, N2, ..., NK }啰挪,其任意連續(xù)子序列可表示為{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K嘲叔。最大連續(xù)子序列是所有連續(xù)子序列中元素和最大的一個(gè)亡呵,例如給定序列{ -2, 11, -4, 13, -5, -2 },其最大連續(xù)子序列為{ 11, -4, 13 }借跪,最大和為20≌海現(xiàn)在增加一個(gè)要求,即還需要輸出該子序列的第一個(gè)和最后一個(gè)元素。
樣例輸入
5
-3 9 -2 5 -4
3
-2 -3 -1
0
樣例輸出
12 9 5
0 -2 -1

令dp[i]表示以i結(jié)尾的數(shù)字當(dāng)前最大和歇由,狀態(tài)轉(zhuǎn)移方程:
dp[i] =max(A[i],dp[i-1]+A[i])
邊界:dp[0]=A[0]卵牍。
程序代碼:

#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

const int maxn = 10010;
int a[maxn];
int dp[maxn];
int choice[maxn];

int main(int argc, char const *argv[])
{
    int k;
    while((scanf("%d",&k)) && k){
        for(int i=0;i<k;i++)
            scanf("%d",&a[i]);
        dp[0] = a[0];
        choice[0] = 1;
        int maxInd = 0;
        for(int i=1;i<k;i++){
            if(a[i] >= dp[i - 1] + a[i]){
                dp[i] = a[i];
                choice[i] = 1;
            }else{
                dp[i] = dp[i-1] + a[i];
                choice[i] = 2;
            }
            if(dp[i] > dp[maxInd])
                maxInd = i;
        }
        if(dp[maxInd] < 0){
            printf("%d %d %d\n",0,a[0],a[k-1] );
        }else{
            int p = maxInd;
            while(choice[p] == 2)
                p--;
            printf("%d %d %d\n",dp[maxInd],a[p],a[maxInd] );
        }
    }
    return 0;
}

4.最長(zhǎng)不下降子序列(LIS)

問(wèn)題:在一個(gè)數(shù)字序列中,找到一個(gè)最長(zhǎng)的子序列(可以不連續(xù))沦泌,使得這個(gè)子序列是不下降的糊昙,例如現(xiàn)有序列A={1,2,3,-1,-2,7,9},其最長(zhǎng)不下降子序列是{1,2,3,7,9}谢谦,長(zhǎng)度為5释牺。
令dp[i]表示以i結(jié)尾的序列當(dāng)前最長(zhǎng)不下降子序列的長(zhǎng)度,則狀態(tài)轉(zhuǎn)移分為兩種情況:

  1. 如果存在A[i]之前的元素Aj回挽,使得A[j]\le A[i]dp[j] +1>dp[i]没咙,則A[i]可跟在A[j]后形成更長(zhǎng)的序列
  2. 如果不存在,那么A[i]只能自己形成一條LIS千劈,長(zhǎng)度為1

狀態(tài)轉(zhuǎn)移方程:
dp[i]=max(1,dp[j]+1),j=1,2,\cdots,i-1\&\&A[j]<A[i]
初始狀態(tài):dp[i]=1,i\in\{1,2,\cdots,n\}
程序代碼:

#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

const int maxn = 10010;
int a[maxn];
int dp[maxn];
int choice[maxn];

int main(int argc, char const *argv[])
{
    int k;
    while((scanf("%d",&k)) && k){
        for(int i=0;i<k;i++)
            scanf("%d",&a[i]);
        dp[0] = a[0];
        choice[0] = 1;
        int maxInd = 0;
        for(int i=1;i<k;i++){
            if(a[i] >= dp[i - 1] + a[i]){
                dp[i] = a[i];
                choice[i] = 1;
            }else{
                dp[i] = dp[i-1] + a[i];
                choice[i] = 2;
            }
            if(dp[i] > dp[maxInd])
                maxInd = i;
        }
        if(dp[maxInd] < 0){
            printf("%d %d %d\n",0,a[0],a[k-1] );
        }else{
            int p = maxInd;
            while(choice[p] == 2)
                p--;
            printf("%d %d %d\n",dp[maxInd],a[p],a[maxInd] );
        }
    }
    return 0;
}

5.最長(zhǎng)公共子序列(LCS)

給定兩字符串A祭刚、B,如sadstory和adminsorry墙牌,其最長(zhǎng)公共子序列為adsory涡驮。
令dp[i][j]為A串的第i號(hào)字符和B串的第j號(hào)字符之前的LCS長(zhǎng)度,狀態(tài)轉(zhuǎn)移有以下兩種情況:
1.如果A[i]==B[j],則dp[i][j]=dp[i-1][j-1]+1
2.否則,dp[i][j]=max(dp[i-1][j],dp[i][j-1])
狀態(tài)轉(zhuǎn)移方程:
dp[i][j]= \begin{cases} dp[i-1][j-1]+1,A[i]==B[i] \\ max(dp[i-1][j],dp[i][j-1],A[i]!=A[j]) \end{cases}
邊界:dp[i][0]=dp[0][j]=0(0\le i \le n,0\le j \le m)
注:使用回溯法可求得具體的公共子串(待補(bǔ))
程序代碼:

#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

const int maxn = 1000;
char A[maxn],B[maxn];
int dp[maxn][maxn];

int main()
{
    gets(A + 1); gets(B + 1); 
    int lenA = strlen(A + 1);
    int lenB = strlen(B + 1);
    for(int i=0;i<= lenA;i++)
        dp[i][0] = 0;
    for(int i=0;i<= lenB;i++)
        dp[0][i] = 0;
    //dp[i][j] = dp[i-1][j-1] + 1,A[i] = A[j]
    //dp[i][j] = max(dp[i-1][j],dp[i][j-1])
    for(int i=1;i<= lenA;i++)
        for(int j=1;j<= lenB;j++)
            if(A[i] == B[j])
                dp[i][j] = dp[i-1][j-1] + 1;
            else
                dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
    printf("%d\n",dp[lenA][lenB]);
}

6.最長(zhǎng)回文子串

問(wèn)題:給定一字符串S喜滨,求其最長(zhǎng)回文子串長(zhǎng)度
如PATZJUJZTACCBCC,最長(zhǎng)回文子串為ATZJUJZTA捉捅,長(zhǎng)度為9
令dp[i][j]表示區(qū)間為[i,j]串是否是回文串,狀態(tài)轉(zhuǎn)移分為以下兩種情況:
1.若S[i]==S[j],那么如果區(qū)間[i+1,j-1]內(nèi)的串仍為回文串的話虽风,那么區(qū)間為[i,j]的串即為回文串
2.若S[i]!=S[j]棒口,那么區(qū)間為[i,j]的串肯定不是回文串
狀態(tài)轉(zhuǎn)移方程:
dp[i][j]= \begin{cases} dp[i+1][j-1],S[i]==S[j] \\ 0,S[i]!=S[j] \end{cases}
邊界:dp[i][i]=1,1\le i\le n,dp[i][i+1]=(S[i]==S[i+1]?1:0)
注意:枚舉方法
如果按照i,j從小到大的順序枚舉焰情,無(wú)法保證dp[i+1][j-1]被計(jì)算過(guò)陌凳,因?yàn)橹怀跏蓟碎L(zhǎng)度為1和2的串,因此可以按串長(zhǎng)度即區(qū)間長(zhǎng)度進(jìn)行枚舉内舟。
程序代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
int const maxn = 1000;
char A[maxn];
int dp[maxn][maxn];

int main()
{
    gets(A);
    int len = strlen(A);

    for(int i=0;i<len;i++)
    {
        dp[i][i] = 1;
        if(i != len - 1 && A[i] == A[i+1])
            dp[i][i+1] = 1;
            ans = 2;
    }

    int ans = 1;
    for(int L = 3;L<=len;L++)
    {
        for(int i=0;i+L-1<len;i++)
        {
            int j = i+L-1;
            if(A[i] != A[j])
                dp[i][j] = 0;
            else
            {
                if(dp[i+1][j-1] == 1)
                {
                    dp[i][j] = 1;
                    ans = L;
                }
                else dp[i][j] = 0;
            }
        }
    }
    printf("%d\n",ans);
}

7.DAG最長(zhǎng)路(待)

8.0-1背包問(wèn)題

問(wèn)題描述:有n件物品合敦,每件物品的重量為w[i],價(jià)值為c[i]⊙橛危現(xiàn)有一個(gè)容量為V的背包充岛,問(wèn)如何選取物品放入背包,使得背包內(nèi)物品的總價(jià)值最大耕蝉,其中每種物品只有一件崔梗。
令dp[i][v]表示前i種物品恰好能放入重量為v的背包所能得到的總價(jià)值,狀態(tài)轉(zhuǎn)移有以下兩種情況:
1.選擇第i種物品垒在,那么問(wèn)題轉(zhuǎn)化為前i-1種物品能夠放入重量為v-w[i]的背包所能獲得的最大價(jià)值蒜魄。
2.不選擇第i種物品,那么當(dāng)前最大價(jià)值即等于前i-1種物品能夠放入重量為v的背包所能獲得的最大價(jià)值。
狀態(tài)轉(zhuǎn)移方程:
dp[i][v]=max(dp[i-1][v],dp[i-1][v-w[i]]+c[i]),1\le i\le n,w[i]\le v\le V
邊界狀態(tài):dp[0][v]=0(0\le v \le V)

空間復(fù)雜度的優(yōu)化
注意到dp[i][j]的計(jì)算只是依賴于i-1階段的V個(gè)狀態(tài)谈为,而不依賴于i-1之前的狀態(tài)旅挤,因此可以通過(guò)滾動(dòng)數(shù)組策略來(lái)去掉物品的維度,狀態(tài)方程:
dp[v]=max(dp[v],dp[v-w[i]]+c[i])(1 \le i \le n,w[i]\le v \le V)

image.png

當(dāng)前第i階段只依賴i-1階段的值伞鲫,因此在枚舉重量v的時(shí)候只能逆序枚舉粘茄,否則會(huì)當(dāng)前i階段的值會(huì)覆蓋i-1階段的值(后面枚舉需要用到)。
程序代碼:

#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

const int maxn = 100; //物品最大數(shù)
const int maxv = 1000; //背包最大重量
//每件物品的重量秕脓,每件物品的價(jià)值柒瓣,重量為v的背包所能裝物品的最大價(jià)值
int w[maxn], c[maxn], dp[maxv];
int selected[maxn]; //記錄每個(gè)物品是否被選擇 

int main(int argc, char const *argv[])
{
    int n,V;
    scanf("%d%d",&n,&V);
    for(int i=0;i<n;i++)
        scanf("%d",&w[i]);
    for(int i=0;i<n;i++)
        scanf("%d",&c[i]);
    //初始邊界,當(dāng)i=0時(shí)吠架,dp[v]=0
    for(int v=0;v<=V;v++)
        dp[v] = 0;
    //注意點(diǎn):
    //1. 滾動(dòng)數(shù)組來(lái)優(yōu)化空間:每次更新時(shí)用到的dp是i-1時(shí)刻的dp值芙贫,更新后變?yōu)閕時(shí)刻的dp值
    //2. 狀態(tài)轉(zhuǎn)移方程: dp[v] = max(dp[v],dp[v - w[i]] + c[i])
    //3. 逆序更新:保證i-1時(shí)刻的值不被覆蓋
    //4. dp[v]此時(shí)保存的是重量為v恰好裝入物品的最大價(jià)值
    //5. 階段狀態(tài)思想:本階段的所有狀態(tài)可有上一階段的所有狀態(tài)推理可得
    //   階段:可選的不同物品,狀態(tài):在給定物品下的不同重量
    //6. 無(wú)后效性:第i階段的所有狀態(tài)取值僅取決于i-1階段的狀態(tài)取值
    //   滿足無(wú)后效性的問(wèn)題可用滾動(dòng)數(shù)組來(lái)求解诵肛,不滿足的可以增加維度
    for(int i=1;i<=n;i++){
        for(int v = V;v>=w[i];v--){
            dp[v] = max(dp[v],dp[v - w[i]] + c[i]);
        }
    }
    //尋找最大的dp[v]
    int k = 0;
    for(int v=0;v<=V;v++){
        if(dp[v] > dp[k])
            k = v;
    }
    printf("%d\n", dp[k]);
    return 0;
}

9.完全背包問(wèn)題

問(wèn)題描述:有n種物品屹培,每種物品的單件重量為w[i],價(jià)值為c[i]≌荩現(xiàn)有一個(gè)容量為V的背包,問(wèn)如何選取物品放入背包蓄诽,使得背包內(nèi)物品的總價(jià)值最大薛训,其中每種物品都有無(wú)窮件。
令dp[i][v]表示前i件物品恰好放入容量為v的背包中所能獲得的最大價(jià)值仑氛,和0-1背包的區(qū)別在于:
1.不放第i件物品乙埃,那么dp[i][v]=dp[i-1][v],同0-1背包
2.放第i件物品锯岖,那么dp[i][v]=dp[i][v-w[i]]+c[i]介袜,這里dp[i][v]依賴階段i的v-w[i]的狀態(tài),因?yàn)槲锲窋?shù)量無(wú)限出吹,所以可以重復(fù)的放物品i
狀態(tài)轉(zhuǎn)移方程:
dp[i][v]=max(dp[i-1][v],dp[i][v-w[i]]+c[i]),1\le i \le n,w[i]\le v\le V
邊界狀態(tài):dp[0][v]=0(0\le v \le V)
同樣遇伞,可以用滾動(dòng)數(shù)組來(lái)去掉物品維度,此時(shí)需要正序枚舉背包容量捶牢,因?yàn)殡A段i的值依賴當(dāng)前階段i鸠珠,需要使用覆蓋的數(shù)據(jù),狀態(tài)轉(zhuǎn)移方程:
dp[v]=max(dp[v],dp[v-w[i]]+c[i])(1\le i \le n,w[i] \le v \le V)

10.完全背包可行方案數(shù)的問(wèn)題

問(wèn)題描述:傳統(tǒng)地秋麸,一個(gè)貨幣系統(tǒng)是由1,5,10,20 或 25,50, 和 100的單位面值組成的渐排,現(xiàn)用這些硬幣支付面值為A的商品,問(wèn)有多少種不同的方案灸蟆,輸出字典順序最小的方案驯耻,這些硬幣無(wú)窮多個(gè)。

問(wèn)題特點(diǎn):相當(dāng)于求下列方程解的個(gè)數(shù):
a_{1}x_{1}+a_{2}x_{2}+\cdots+a_{n}x_{n}=M
其中a_{1},\cdots,a_{n}表示n個(gè)硬幣的面值,x_{1},\cdots,x_{n}表示組合方案可缚。
令dp[i][v]表示前i個(gè)硬幣恰能組成面值為v的方案數(shù)霎迫,則狀態(tài)轉(zhuǎn)移方程:
dp[i][v]=dp[i-1][v]+dp[i][v-w[i]]
初始化:dp[0]=1,其余為0
使用滾動(dòng)數(shù)組,狀態(tài)轉(zhuǎn)移方程可轉(zhuǎn)化為:
dp[v]=dp[v]+dp[v-w[i]]
進(jìn)行正序枚舉面值v即可
程序代碼:

#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

/*
    1.此類問(wèn)題為完全背包的可行解個(gè)數(shù)問(wèn)題城看,需要掌握
    2.令dp[i][v]表示前i個(gè)物品恰能裝滿重量為w的方案數(shù)
    3.狀態(tài)轉(zhuǎn)移方程:dp[i][v] = dp[i-1][v] + dp[i][v-w[i]]女气,dp[:][0] = 1
    4.討論:第一種狀態(tài)轉(zhuǎn)移:不選物品i,狀態(tài)轉(zhuǎn)移取決于i-1階段
    第二種狀態(tài)轉(zhuǎn)移:選擇物品i测柠,由于物品i的個(gè)數(shù)不受限制炼鞠,因此
    狀態(tài)轉(zhuǎn)移取決于第i階段,可以選擇多個(gè)物品i,但會(huì)受到容量v的限制
    5.可以將上述二維狀態(tài)轉(zhuǎn)移方程利用滾動(dòng)數(shù)組變成一維
    6.進(jìn)行正序dp
*/

const int maxn = 30;
const int maxm = 10010;
long long dp[maxm],w[maxn];

int main(int argc, char const *argv[])
{
    int n,V;
    scanf("%d%d",&n,&V);
    for(int i=1;i<=n;i++)
        scanf("%lld",&w[i]);
    //初始化
    dp[0] = 1;
    for(int i=1;i<=V;i++)
        dp[i] = 0;
    for(int i=1;i<=n;i++){
        for(int v=w[i];v<=V;v++)
            dp[v] = dp[v] + dp[v-w[i]];
    }
    printf("%lld\n",dp[V] );
    return 0;
}

11.非完全背包問(wèn)題

問(wèn)題描述:有1元轰胁、5元谒主、50元、100元赃阀、500元的硬幣各1霎肯、5、10榛斯、50观游、100、500枚⊥运祝現(xiàn)在要用這些硬幣來(lái)支付A元懂缕,有多少種支付方案。并且輸出字典順序最小的方案王凑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搪柑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子索烹,更是在濱河造成了極大的恐慌工碾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件百姓,死亡現(xiàn)場(chǎng)離奇詭異渊额,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瓣戚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門端圈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人子库,你說(shuō)我怎么就攤上這事舱权。” “怎么了仑嗅?”我有些...
    開(kāi)封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵宴倍,是天一觀的道長(zhǎng)张症。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鸵贬,這世上最難降的妖魔是什么俗他? 我笑而不...
    開(kāi)封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮阔逼,結(jié)果婚禮上兆衅,老公的妹妹穿的比我還像新娘。我一直安慰自己嗜浮,他們只是感情好羡亩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著危融,像睡著了一般畏铆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吉殃,一...
    開(kāi)封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天辞居,我揣著相機(jī)與錄音,去河邊找鬼蛋勺。 笑死瓦灶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抱完。 我是一名探鬼主播倚搬,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乾蛤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起捅僵,我...
    開(kāi)封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤家卖,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后庙楚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體上荡,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年馒闷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了酪捡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纳账,死狀恐怖逛薇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疏虫,我是刑警寧澤永罚,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布啤呼,位于F島的核電站,受9級(jí)特大地震影響呢袱,放射性物質(zhì)發(fā)生泄漏官扣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一羞福、第九天 我趴在偏房一處隱蔽的房頂上張望惕蹄。 院中可真熱鬧,春花似錦治专、人聲如沸卖陵。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赶促。三九已至,卻和暖如春挟炬,著一層夾襖步出監(jiān)牢的瞬間鸥滨,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工谤祖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婿滓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓粥喜,卻偏偏與公主長(zhǎng)得像凸主,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子额湘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容