加了限制條件的動態規劃

對於加了限制條件的動態規劃,經常需要進行輸入數據的預處理

題目:購物單問題====================================================

王強今天很開心,公司發給N元的年終獎。王強決定把年終獎用於購物,他把想買的物品分爲兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:
主件 附件
電腦 打印機,掃描儀
書櫃 圖書
書桌 檯燈,文具
工作椅
如果要買歸類爲附件的物品,必須先買該附件所屬的主件。每個主件可以有 0 個、 1 個或 2 個附件。附件不再有從屬於自己的附件。王強想買的東西很多,爲了不超出預算,他把每件物品規定了一個重要度,分爲 5 等:用整數 1 5 表示,第 5 等最重要。他還從因特網上查到了每件物品的價格(都是 10 元的整數倍)。他希望在不超過 N 元(可以等於 N 元)的前提下,使每件物品的價格與重要度的乘積的總和最大。
    設第 j 件物品的價格爲 v[j] ,重要度爲 w[j] ,共選中了 k 件物品,編號依次爲 j 1 , j 2 ,……, j k ,則所求的總和爲:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 爲乘號)
    請你幫助王強設計一個滿足要求的購物單。
注意:(1)先進行輸入數據的預處理。這裏重要度沒有優先級問題,也就是說沒有重要度比較高就先選,而是一個權重問題而已,所以可以設置W=價格x重要度,只需求出最大的W即可。(2)附件的問題。選附件時必須先選擇主件,所以這個輸入好像是有順序的。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
using namespace std;
   
int main(){
    int v[61];  //每件物品的價格
    int vp[61];  //每件物品的價格和重要度的乘積
    int q[61];   //所屬附件
    int dp[61][32001];
    int N;
    int m;
    while(cin>>N>>m){
        for(int i=0;i<61;i++){
            memset(dp[i],0,sizeof(dp[i]));
        }
        int impor;
        for(int i=1;i<=m;i++){
            
            cin>>v[i]>>impor>>q[i];
            vp[i]=v[i]*impor;
        }
         
        for(int i=1;i<=m;i++){
            for(int j=1;j<=N;j++){
                if(q[i]==0){
                    if(v[i]<=j){
                        dp[i][j]=max(dp[i-1][j-v[i]]+vp[i],dp[i-1][j]);
                    }
                }
                else{
                    if(v[i]+v[q[i]]<=j){
                        dp[i][j]=max(dp[i-1][j-v[i]]+vp[i],dp[i-1][j]);
                    }
                }
            }
        }
        cout<<dp[m][N]<<endl;
    }
    return 0;
}

這裏有個小疑問: 這樣會不會造成全部選的都是附件,因爲程序並沒有在選附件的條件下先選主件,而只是判斷(附件+主件的重量)<j。 除非輸入的順序是先輸入主件,屬於這個主件的附件在這個主件後輸入。如果輸入順序是隨意的,比如過前10個輸入的全是附件,那好像就會造成這個問題。

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