第5次數據結構上機(01揹包遞歸求解)

實驗名稱:用遞歸算法解決實際問題

指導教師:           王瑩潔              

專業班級:       計163-1        

姓   名:      曹欣宇              

學   號:      201658503125             

一、實驗題目

編寫一個程序exp5-2.cpp,求解揹包問題:設有不同價值、不同重量的物品n件,求從這n件物品中選取一部分物品的方案,使選中物品的總重量不超過指定的限制重量,但選中物品的總價值最大。

二、實驗目的


靈活運用遞歸算法解決一些較複雜應用問題。


三、實驗步驟

(包括基本設計思路、算法設計、函數相關說明、輸入與輸出以及程序運行結果)

基本設計思路:遞歸。

算法設計:

遞歸公式:bag(n,c)=max{bag(n-1,c), bag(n-1,c-w[n])+v[n]},其中,n爲物品個數,c爲揹包最大容納量,w[]爲每個物品的重量,v[]爲每個物品的價值。

具體算法:

設置一個判斷數組ju[],規定值爲1則爲選中,值爲0則爲沒選中,進入遞歸後,若n或m等於零,則最優解爲0;若物品值大於c,則相當於物品數量減1,即返回bag(n-1,c),並且ju[]賦值爲0,否則根據遞歸公式,比較兩公式的值,決定進行哪一步遞歸,其中,若執行bag(n-1,c-w[n])+v[n]公式,表示已選中該物品,n的數量減1,容納重量減去該物品的重量,總價值加上物品的價值,並且ju[]賦值爲1,反之,若執行bag(n-1,c),表示沒有選中,n數量減1。最後,主函數中,bag函數的返回值即爲最大價值,然後根據ju[]數組值來確定選取了哪些物品。

函數相關說明:int bag(int n,int c)//進行遞歸調用

輸入:5

          10,100

          8,90

          9,120

          12,150

          6,80

          20

輸出:見運行圖。

運行結果:


五、實驗心得體會

通過這次實驗,我更加深刻理解了遞歸,遞歸不需要糾結於具體的問題解決的路子,只需要注重在問題大化小之後的情況就好。

 

六、源程序清單(代碼)

#include <stdio.h>
#include <stdlib.h>
int w[50],v[50];
int ju[50];

int bag(int n,int c)
{
    if (n==0||c==0)
        return 0;
    else
    {

        if ((c>=w[n])&&(bag(n-1,c)<(bag(n-1,c-w[n])+v[n])))
        {
            ju[n]=1;
            return bag(n-1,c-w[n])+v[n];
        }
        else
        {
            ju[n]=0;
            return bag(n-1,c);
        }
    }
}
int main()
{
    int n,i,j;
    int c;
    int max_v;
    printf("物品總數:\n");
    scanf("%d",&n);
    for(j=1; j<=n; j++)
    {
        printf("第%d種物品(重量,價值):",j);
        scanf("%d,%d",&w[j],&v[j]);
    }
    printf("揹包所能承受的總重量爲:");
    scanf("%d",&c);
    printf("最佳填裝方案:\n");
    max_v=bag(n,c);
    for(i=1; i<=n; i++)
    {
        if(ju[i]==1)
            printf("第%d種物品\n",i);
    }
    printf("總價值:%d",max_v);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章