最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言?深入理解動(dòng)態(tài)規(guī)劃之計(jì)數(shù)類DP

 更新時(shí)間:2022年04月12日 15:06:56   作者:小羊努力變強(qiáng)  
動(dòng)態(tài)規(guī)劃可謂是大名鼎鼎,筆試面試中的高頻考點(diǎn),也是重點(diǎn)難點(diǎn),動(dòng)態(tài)規(guī)劃類型題目靈活多變,難度系數(shù)也相對(duì)較高,往往我們做不好動(dòng)態(tài)規(guī)劃的題目就會(huì)與心儀的offer失之交臂,本篇文章我們就一起來(lái)研究一下動(dòng)態(tài)規(guī)劃的計(jì)數(shù)類DP

寫在前面

之前講過(guò)背包問(wèn)題線性DP,區(qū)間DP,不知道大家忘了嗎,這次是計(jì)數(shù)類DP

石子合并

在這里插入圖片描述

在這里插入圖片描述

老規(guī)矩,先畫圖。

思路:把1,2,3, … n分別看做n個(gè)物體的體積,這n個(gè)物體均無(wú)使用次數(shù)限制,問(wèn)恰好能裝滿總體積為n的背包的總方案數(shù)(完全背包問(wèn)題變形)

初值問(wèn)題:

求最大值時(shí),當(dāng)都不選時(shí),價(jià)值顯然是 0

而求方案數(shù)時(shí),當(dāng)都不選時(shí),方案數(shù)是 1(即前 i 個(gè)物品都不選的情況也是一種方案),所以需要初始化為 1

即:for (int i = 0; i <= n; i ++) f[i][0] = 1;

等價(jià)變形后: f[0] = 1

狀態(tài)計(jì)算:

f[i][j]表示前i個(gè)整數(shù)(1,2…,i)恰好拼成j的方案數(shù)

求方案數(shù):把集合選0個(gè)i,1個(gè)i,2個(gè)i,…全部加起來(lái)

f[i][j] = f[i - 1][j] + f[i - 1][j - i] + f[i - 1][j - 2 * i] + …;

f[i][j - i] = f[i - 1][j - i] + f[i - 1][j - 2 * i] + …;

因此 f[i][j]=f[i−1][j]+f[i][j−i]; (這一步類似完全背包的推導(dǎo))

樸素做法

// f[i][j] = f[i - 1][j] + f[i][j - i]
#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 7, mod = 1e9 + 7;

int f[N][N];

int main() {
    int n;
    cin >> n;

    for (int i = 0; i <= n; i ++) {
        f[i][0] = 1; // 容量為0時(shí),前 i 個(gè)物品全不選也是一種方案
    }

    for (int i = 1; i <= n; i ++) {
        for (int j = 0; j <= n; j ++) {
            f[i][j] = f[i - 1][j] % mod; // 特殊 f[0][0] = 1
            if (j >= i) f[i][j] = (f[i - 1][j] + f[i][j - i]) % mod;
        }
    }

    cout << f[n][n] << endl;
}

等價(jià)變形

// f[i][j] = f[i - 1][j] + f[i][j - i]
#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 7, mod = 1e9 + 7;

int f[N];

int main() {
    int n;
    cin >> n;


    f[0] = 1; // 容量為0時(shí),前 i 個(gè)物品全不選也是一種方案

    for (int i = 1; i <= n; i ++) {
        for (int j = i; j <= n; j ++) {
            f[j] = (f[j] + f[j - i]) % mod;
        }
    }

    cout << f[n] << endl;
}

上面是完全背包問(wèn)題的解法,再來(lái)看看不用完全背包問(wèn)題求解

在這里插入圖片描述

狀態(tài)計(jì)算:分兩部分

  • 這j個(gè)數(shù)中存在最小值為1的數(shù) 先去掉這一個(gè)1,其他部分表示為總和為i-1,恰好由j-1個(gè)數(shù)f[i-1][j-1]
  • 這j個(gè)數(shù)中存在的最小值都>1 j個(gè)數(shù)都>1,讓j個(gè)數(shù)都-1,求總和為j-i,由j個(gè)數(shù)的方案表示:f[i-j][j]

綜上所述:f[i][j] = f[i - 1][j - 1] + f[i - j][j];

//非背包做法
//狀態(tài)表示:f[i][j] 所有總和是i,并且恰好可以表示成j個(gè)數(shù)的和的方案
#include <bits/stdc++.h>

using namespace std;

const int N = 1010, mod = 1e9 + 7;

int n;
int f[N][N];

int main()
{
    cin >> n;

    f[0][0] = 1;
    for (int i = 1; i <= n; i ++ )
        //i最多表示成i個(gè)數(shù)的和,因此j<=i
        for (int j = 1; j <= i; j ++ )
            f[i][j] = (f[i - 1][j - 1] + f[i - j][j]) % mod;

    int res = 0;
    for (int i = 1; i <= n; i ++ ) res = (res + f[n][i]) % mod;

    cout << res << endl;

    return 0;
}

到此這篇關(guān)于C語(yǔ)言 深入理解動(dòng)態(tài)規(guī)劃之計(jì)數(shù)類DP的文章就介紹到這了,更多相關(guān)C語(yǔ)言 計(jì)數(shù)類DP內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

屏东县| 南阳市| 应用必备| 凉城县| 武宣县| 星座| 漳平市| 绵阳市| 额尔古纳市| 图木舒克市| 昭觉县| 南丰县| 宝兴县| 波密县| 长顺县| 镇安县| 秦安县| 永登县| 醴陵市| 上饶市| 遵化市| 航空| 石景山区| 勃利县| 怀安县| 丰都县| 上饶市| 甘孜| 华坪县| 桂东县| 闸北区| 定州市| 濮阳县| 宜兴市| 宁陵县| 苏尼特左旗| 抚顺县| 治县。| 岢岚县| 安丘市| 广西|