日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

从0-1背包问题学习回溯法、分支界限法、动态规划

發(fā)布時(shí)間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从0-1背包问题学习回溯法、分支界限法、动态规划 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、0-1背包問(wèn)題的描述

下面將使用回溯法、分支界限法、動(dòng)態(tài)規(guī)劃法來(lái)分析和解決此問(wèn)題。


二、回溯法

(1)算法步驟


(2)代碼如下(沒(méi)有裁剪函數(shù)):

用i和n來(lái)判斷結(jié)束與否,是因?yàn)榻饪臻g結(jié)構(gòu)是完全二叉樹,用兩節(jié)點(diǎn)間的邊的深度表示物品序號(hào),用兩節(jié)點(diǎn)之間的邊的01值表示該物品選擇與否。


#include<stdio.h> int n, c, bestp;//物品的個(gè)數(shù),背包的容量,最大價(jià)值 int p[10000], w[10000], x[10000], bestx[10000];//物品的價(jià)值,物品的重量,x[i]暫存物品的選中情況,物品的選中情況void Backtrack(int i, int cp, int cw) { //cw當(dāng)前包內(nèi)物品重量,cp當(dāng)前包內(nèi)物品價(jià)值int j;if (i>n)//回溯結(jié)束{if (cp>bestp){bestp = cp;for (i = 0; i <= n; i++)//這里從0開始也無(wú)妨,因?yàn)楹竺孑敵鍪菑?開始的 bestx[i] = x[i];}}elsefor (j = 0; j <= 1; j++){x[i] = j;if (cw + x[i] * w[i] <= c){cw += w[i] * x[i];cp += p[i] * x[i];Backtrack(i + 1, cp, cw);cw -= w[i] * x[i];cp -= p[i] * x[i];}} }int main() {int i;bestp = 0;printf("請(qǐng)輸入背包最大容量:\n");scanf("%d", &c);printf("請(qǐng)輸入物品個(gè)數(shù):\n");scanf("%d", &n);printf("請(qǐng)依次輸入物品的重量:\n");for (i = 1; i <= n; i++)scanf("%d", &w[i]);printf("請(qǐng)依次輸入物品的價(jià)值:\n");for (i = 1; i <= n; i++)scanf("%d", &p[i]);Backtrack(1, 0, 0);printf("最大價(jià)值為:\n");printf("%d\n", bestp);printf("被選中的物品依次是(0表示未選中,1表示選中)\n");for (i = 1; i <= n; i++)printf("%d ", bestx[i]);printf("\n");getchar(); getchar();return 0; }

2、動(dòng)態(tài)規(guī)化

#include<stdlib.h> #include<stdio.h>int V[200][200];//前i個(gè)物品裝入容量為j的背包中獲得的最大價(jià)值 int max(int a, int b) //一個(gè)大小比較函數(shù),用于當(dāng)總重大于第I行時(shí) {if (a >= b)return a;else return b; }void Knap(int n, int w[], int v[], int x[], int C) {int i, j;for (i = 0; i <= n; i++)V[i][0] = 0;for (j = 0; j <= C; j++)//j居然是離散的V[0][j] = 0;for (i = 0; i <= n - 1; i++)for (j = 0; j <= C; j++)if (j<w[i])V[i][j] = V[i - 1][j];elseV[i][j] = max(V[i - 1][j], V[i - 1][j - w[i]] + v[i]);//輸出相應(yīng)的選擇物品j = C;for (i = n - 1; i >= 0; i--){if (V[i][j]>V[i - 1][j]){x[i] = 1;j = j - w[i];}elsex[i] = 0;}printf("選中的物品是:\n");for (i = 0; i<n; i++)printf("%d ", x[i]);printf("\n");}int main() {int s;//獲得的最大價(jià)值int w[4];//物品的重量 重量 價(jià)值 和物品的狀態(tài) 均對(duì)應(yīng)著存到數(shù)組中,物品從1開始。 int v[4];//物品的價(jià)值int x[4];//物品的選取狀態(tài) 選中則是1 沒(méi)選中為0 int n, i;int C;//背包最大容量n = 4;printf("請(qǐng)輸入背包的最大容量:\n");scanf("%d", &C);printf("物品數(shù):\n");scanf("%d", &n);printf("請(qǐng)分別輸入物品的重量:\n");for (i = 0; i<n; i++)scanf("%d", &w[i]);printf("請(qǐng)分別輸入物品的價(jià)值:\n");for (i = 0; i<n; i++)scanf("%d", &v[i]);Knap(n, w, v, x, C);printf("最大物品價(jià)值為:\n");printf("%d\n", s);system("pause");return 0; }


總結(jié)

以上是生活随笔為你收集整理的从0-1背包问题学习回溯法、分支界限法、动态规划的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。