欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++動(dòng)態(tài)規(guī)劃中關(guān)于背包問題講解

 更新時(shí)間:2023年03月15日 10:03:39   作者:清風(fēng)何渡  
可能有些讀者有接觸過動(dòng)態(tài)規(guī)劃,可能也有一些讀者以前完全不知道動(dòng)態(tài)規(guī)劃這個(gè)東西,別擔(dān)心,我這篇文章會(huì)為讀者做一個(gè)入門,好讓讀者掌握這個(gè)重要的知識(shí)點(diǎn)

一、分割等和子集-最后一塊石頭的重量II

背包問題,難點(diǎn)往往在第一步:dp數(shù)組表示什么

分割等和子集問題,較好的方式是:求裝滿背包后最大重量是多少(有點(diǎn)繞哈哈)

這是個(gè)題型:對(duì)于判斷能不能恰好裝滿背包的問題,用dp表示重量,判斷是否最終的dp[m]==m

bool canPartition(int* nums, int numsSize){
    //首先數(shù)組元素求和的sum,若sum%2==1,返回false
    //若sum%2==0,定義m=sum/2,n=numsSize
    //則問題變成了能否裝滿容量為m的背包
    //進(jìn)一步變成了求裝滿容量為m的背包得到的最大價(jià)值量(本題價(jià)值量即為重量)
    //1.dp[j]表示裝滿容量為j的背包能獲得的最大價(jià)值量
    //2.遞推式:dp[j]=fmax(dp[j],dp[j-nums[i]]+nums[i]);
    //3.dp數(shù)組初始化:dp[i]=0;
    //4.遍歷順序:0-1背包順序(滾動(dòng)數(shù)組)
    int sum=0;
    for(int i=0;i<numsSize;i++) sum+=nums[i];
    if(sum%2==1) return false;
    int m=sum/2,n=numsSize;
    int dp[m+1];
    for(int j=0;j<=m;j++) dp[j]=0;
    for(int i=0;i<n;i++){
        for(int j=m;j>=nums[i];j--)
            dp[j]=fmax(dp[j],dp[j-nums[i]]+nums[i]);
    }
    if(dp[m]==m) return true;
    else return false;
}

二、目標(biāo)和

求組合數(shù)模板:dp[0]=1;dp[j]+=dp[j-nums[i]];

int findTargetSumWays(int* nums, int numsSize, int target){
    //首先數(shù)組元素求和的sum,若滿足題意,m+(m-target)=sum
    //若(sum+target)%2==1,返回0;
    //若sum<abs(target),返回0;
    //否則,有m=(sum+target)/2;
    //問題就變成了整數(shù)m可以有多少表達(dá)式表示出
    //進(jìn)一步變成了求裝滿容量為m的背包的最大組合數(shù)
    //1.dp[j]表示裝滿容量為j的背包的最大表達(dá)式的組合數(shù)
    //2.遞推式:
    //組合問題模板:dp[0]=1;dp[j]+=dp[j-nums[i]];
    //3.dp數(shù)組初始化:dp[i]=0;dp[0]=1;
    int sum=0;
    for(int i=0;i<numsSize;i++) sum+=nums[i];
    if(sum<abs(target)||(sum+target)%2==1) return 0;
    int m=(sum+target)/2,n=numsSize;
    int dp[m+1];
    for(int i=1;i<=m;i++) dp[i]=0;
    dp[0]=1;
    for(int i=0;i<n;i++){
        for(int j=m;j>=nums[i];j--)
            dp[j]+=dp[j-nums[i]];
    }
    return dp[m];
}

三、一和零

注意二維滾動(dòng)數(shù)組不能寫在同一個(gè)for循環(huán)中,這題背一下

int findMaxForm(char ** strs, int strsSize, int m, int n){
    //本題是二維背包,不過是比一維多了一步而已
    //1.dp[i][j]表示背包容量為i個(gè)0、j個(gè)1時(shí),最多能裝的物品個(gè)數(shù)
    //2.遞推式:
    //dp[i][j]=fmax(dp[i][j],dp[i-cnt0][j-cnt1]+1);
    //3.dp數(shù)組初始化:
    //dp[i][j]=0;
    //4.遍歷順序:二維滾動(dòng)數(shù)組(注意不能把i和j寫在同一個(gè)for循環(huán)中)
    int dp[m+1][n+1];
    for(int i=0;i<=m;i++){
        for(int j=0;j<=n;j++)
            dp[i][j]=0;
    }
    for(int k=0;k<strsSize;k++){
        int cnt0=0,cnt1=0;
        int len=strlen(strs[k]);
        for(int i=0;i<len;i++){
            if(strs[k][i]=='0') cnt0++;
            else cnt1++;
        }
        for(int i=m;i>=cnt0;i--){
            for(int j=n;j>=cnt1;j--){
                dp[i][j]=fmax(dp[i][j],dp[i-cnt0][j-cnt1]+1);
            }
        }
    }
    return dp[m][n];
}

四、零錢兌換II

多重背包和0-1背包唯一的區(qū)別在遍歷順序

我們知道01背包內(nèi)嵌的循環(huán)是從大到小遍歷,為了保證每個(gè)物品僅被添加一次。

而完全背包的物品是可以添加多次的,所以要從小到大去遍歷

int change(int amount, int* coins, int coinsSize){
    int m=amount,n=coinsSize;
    int dp[m+1];
    for(int i=1;i<=m;i++) dp[i]=0;
    dp[0]=1;
    for(int i=0;i<n;i++){
        for(int j=coins[i];j<=m;j++)
            dp[j]+=dp[j-coins[i]];
    }
    return dp[m];
}

五、排列與組合

組合總數(shù)IV(排列問題)

本題要求的是排列數(shù)(即考慮排列順序)

求排列數(shù),外層遍歷重量,內(nèi)層遍歷物品,且均為從左到右遍歷

int combinationSum4(int *nums,int n,int m){
    //1.dp[j]表示背包容量為j時(shí),有多少種方法能使背包被裝滿“
    //2.遞推式:
    //dp[j]+=dp[j-nums[i]];
    //3.初始化:
    //dp[i]=0;dp[0]=1;
    //4.遍歷順序:
    //本題要求的是排列數(shù)(即考慮排列順序)
    //求排列數(shù),外層遍歷重量,內(nèi)層遍歷物品,且均為從左到右遍歷
    int dp[m+1];
    for(int i=1;i<=m;i++) dp[i]=0;
    dp[0]=1;
    for(int j=0;j<=m;j++){
        for(int i=0;i<n;i++){
            if(j>=nums[i]&&dp[j]<INT_MAX-dp[j-nums[i]])
                dp[j]+=dp[j-nums[i]];
        }
    }
    return dp[m];
}

零錢兌換(組合問題)

本題要求的是組合數(shù)(即不考慮排列順序)

求組合數(shù),外層遍歷物品,內(nèi)層遍歷重量,且均為從左到右遍歷

int int coinChange(int* coins, int coinsSize, int amount){
    //1.dp[j]表示背包容量為j時(shí),有多少種方法能使背包被裝滿“
    //2.遞推式:
    //dp[j]+=dp[j-coins[i]];
    //3.初始化:
    //dp[i]=0;dp[0]=1;
    //4.遍歷順序:
    //本題要求的是組合數(shù)(即不考慮排列順序)
    //求組合數(shù),外層遍歷物品,內(nèi)層遍歷重量,且均為從左到右遍歷
    int m=amount,n=coinsSize;
    int dp[m+1];
    for(int i=1;i<=m;i++) dp[i]=0;
    dp[0]=1;
    for(int i=0;i<n;i++){
        for(int j=coins[i];j<=m;j++)
            dp[j]+=dp[j-coins[i]];
    }
    return dp[m];
}

到此這篇關(guān)于C++動(dòng)態(tài)規(guī)劃中關(guān)于背包問題講解的文章就介紹到這了,更多相關(guān)C++動(dòng)態(tài)規(guī)劃背包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt菜單QMenu和菜單欄QMenuBar及自定義菜單用法

    Qt菜單QMenu和菜單欄QMenuBar及自定義菜單用法

    本文主要介紹了Qt菜單QMenu和菜單欄QMenuBar及自定義菜單用法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C語言實(shí)現(xiàn)單鏈表的示例詳解

    C語言實(shí)現(xiàn)單鏈表的示例詳解

    給需要考研的同學(xué)一個(gè)參考,單鏈表作為常見數(shù)據(jù)結(jié)構(gòu)的一種,這里記錄C語言實(shí)現(xiàn)單鏈表,文章通過代碼示例介紹的非常詳細(xì),具有一頂?shù)膮⒖純r(jià)值,需要的朋友可以參考下
    2023-09-09
  • C語言遞歸實(shí)現(xiàn)線索二叉樹

    C語言遞歸實(shí)現(xiàn)線索二叉樹

    這篇文章主要介紹了C語言遞歸實(shí)現(xiàn)線索二叉樹,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • C++ 中的Lambda表達(dá)式寫法

    C++ 中的Lambda表達(dá)式寫法

    在 C++ 11 中,lambda 表達(dá)式(通常稱為 “l(fā)ambda”)是一種在被調(diào)用的位置或作為參數(shù)傳遞給函數(shù)的位置定義匿名函數(shù)對(duì)象的簡便方法,下面通過本文給大家介紹C++ 中的Lambda表達(dá)式寫法,需要的朋友參考下吧
    2017-02-02
  • 有關(guān)C++中類類型轉(zhuǎn)換操作符總結(jié)(必看篇)

    有關(guān)C++中類類型轉(zhuǎn)換操作符總結(jié)(必看篇)

    下面小編就為大家?guī)硪黄嘘P(guān)C++中類類型轉(zhuǎn)換操作符總結(jié)(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • C++獲取系統(tǒng)時(shí)間的三種方法

    C++獲取系統(tǒng)時(shí)間的三種方法

    在?C++?編程中,獲取系統(tǒng)時(shí)間是一項(xiàng)常見任務(wù),無論是記錄日志、計(jì)算程序運(yùn)行時(shí)間,還是實(shí)現(xiàn)計(jì)時(shí)功能,都需要獲取當(dāng)前的系統(tǒng)時(shí)間,本文將介紹幾種在?C++?中獲取系統(tǒng)時(shí)間的方法,并提供相應(yīng)的代碼示例,需要的朋友可以參考下
    2024-09-09
  • C/C++ 進(jìn)程通訊(命名管道)的實(shí)例

    C/C++ 進(jìn)程通訊(命名管道)的實(shí)例

    下面小編就為大家?guī)硪黄狢/C++ 進(jìn)程通訊(命名管道)的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • c++類型轉(zhuǎn)換及RTTI運(yùn)行階段類型識(shí)別

    c++類型轉(zhuǎn)換及RTTI運(yùn)行階段類型識(shí)別

    這篇文章主要為大家介紹了c++類型轉(zhuǎn)換及RTTI運(yùn)行階段類型識(shí)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2023-05-05
  • Qt教程之QSqlQueryModel的使用詳解

    Qt教程之QSqlQueryModel的使用詳解

    QSqlQueryModel是QSqlTableModel的父類,它封裝了執(zhí)行SELECT語句從數(shù)據(jù)庫查詢數(shù)據(jù)的功能,本文將為大家介紹一下QSqlQueryModel的使用,需要的可以參考一下
    2022-11-11
  • C語言結(jié)構(gòu)體內(nèi)存對(duì)齊詳解

    C語言結(jié)構(gòu)體內(nèi)存對(duì)齊詳解

    大家好,本篇文章主要講的是C語言結(jié)構(gòu)體內(nèi)存對(duì)齊詳解,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01

最新評(píng)論