DP複習——有依賴的揹包問題
有依賴的揹包問題
這類問題是01揹包的變形。所有的物品分為兩類,一類是主件,另一類是附件,每一個附件都有它的主件,選取它的主件之後才能選取附件。
例題——金明的預算方案
【問題描述】
金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“ 你的房間需要購買哪些物品,怎麼佈置,你說了算,只要不超過 N元錢就行 ”。今天一早,金明就開始做預算了,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:
工作椅無如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有 0個1 個或 2個附件。附件不再有從屬於自己的附件。金明想買的東西很多,肯定會超過媽媽限定的 N元。於是,他把每件物品規定了一個重要度,分為 5等:用整數 1∼5表示,第5等最重要。他還從因特網上查到了每件物品的價格(都是 10元的整數倍)。他希望在不超過 N元(可以等於 N元)的前提下,使每件物品的價格與重要度的乘積的總和最大。
設第 j件物品的價格為 v[j],重要度為 w[j],共選中了 k件物品,編號依次為 j1,j2,⋯⋯,jk,則所求的總和為:v[j1]×w[j1]+v[j2]×w[j2]+⋯+v[jk]×w[jk]請你幫助金明設計一個滿足要求的購物單。
【輸入檔案】
輸入檔案 budget.in 的第
1行,為兩個正整數,用一個空格隔開:N m(其中 N(<32000)表示總錢數,m(<60)為希望購買物品的個數)從第 2行到第 m+1行,第 j行給出了編號為 j−1的物品的基本資料,每行有 3個非負整數v p q其中 v表示該物品的價格(v<10000),p表示該物品的重要(1∼5),q表示該物品是主件還是附件。如果 q=0,表示該物品為主件,如果q>0,表示該物品為附件,q是所屬主件的編號)
【輸出檔案】
輸出檔案 budget.out 只有一個正整數,為不超過總錢數的物品的價格與重要度乘積的總和的最大值(<200000)。
題解
我們找到這道題目的一句關鍵句:每一個主件至多有2個附件。也就是說我們在判斷一個主件的時候有這幾種方法:
- 什麼都不選
- 只選主件
- 主件+附件1
- 主件+附件2
- 主件+附件1+附件2
五種方法。
就這樣吧。
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int num=0;
char c=' ';
bool flag=true;
for(;c>'9'||c<'0';c=getchar())
if(c=='-')
flag=false ;
for(;c>='0'&&c<='9';num=num*10+c-48,c=getchar());
return flag ? num : -num;
}
const int maxn=100;
int n,m,val[maxn][3],imp[maxn][3];
void init()
{
n=read();
m=read();
for(int i=1;i<=m;i++)
{
int v=read();
int p=read();
int q=read();
if (!q)
{
val[i][0]=v;
imp[i][0]=p;
}
else
{
if(!val[q][1])
{
val[q][1]=v;
imp[q][1]=p;
}
else
{
val[q][2]=v;
imp[q][2]=p;
}
}//每個主件只會有兩個附件
}
}
int f[maxn][70000];//這裡第二維要開得大一點。。我找了好久錯誤哦
void dp()
{
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if (j-val[i][0]>=0)
{
f[i][j]=max(f[i-1][j],f[i-1][j-val[i][0]]+val[i][0]*imp[i][0]);
//只主件
if (j-val[i][0]-val[i][1]>=0)
f[i][j]=max(f[i][j],f[i-1][j-val[i][0]-val[i][1]]+val[i][0]*imp[i][0]+val[i][1]*imp[i][1]);
//主件+附件1
if (j-val[i][0]-val[i][2]>=0)
f[i][j]=max(f[i][j],f[i-1][j-val[i][0]-val[i][2]]+val[i][0]*imp[i][0]+val[i][2]*imp[i][2]);
//主件+附件2
if (j-val[i][0]-val[i][1]-val[i][2]>=0)
f[i][j]=max(f[i][j],f[i-1][j-val[i][0]-val[i][1]-val[i][2]]+val[i][0]*imp[i][0]+val[i][1]*imp[i][1]+val[i][2]*imp[i][2]);
//主件+附件1+附件2
}
else
f[i][j] = f[i-1][j];
//不選主件
}
}
printf("%d\n",f[m][n]);
}
int main()
{
init();
dp();
return 0;
}
相關推薦
DP複習——有依賴的揹包問題
有依賴的揹包問題 這類問題是01揹包的變形。所有的物品分為兩類,一類是主件,另一類是附件,每一個附件都有它的主件,選取它的主件之後才能選取附件。 例題——金明的預算方案 【問題描述】 金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用的
hdu-1561 The more, The Better (樹形dp入門,有依賴的揹包問題
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4954
2018.11.09【NOIP2006】【洛谷P1064】金明的預算方案(有依賴的揹包問題)
傳送門 解析: 首先我並沒有讀完題。。我也沒有管什麼只有兩個依賴,,我直接寫的最裸的單層依賴的揹包問題。。。(其實依賴下面套分組還比這個要噁心)。 思路: 由於我們直接列舉所有策略,對於一個物品集合是
BZOJ.4910.蘋果樹(樹形依賴揹包 DP 單調佇列)
BZOJ 洛谷 \(shadowice\)已經把他的思路說的很清楚了,可以先看一下會更好理解? 這篇主要是對\(Claris\)題解的簡單說明。與\(shadowice\)的做法還是有差異的(比如並沒有明顯用到後序遍歷的性質),而且用這種寫法可能跑的比較輕鬆? 問題等價於樹形依賴揹包,允許一條鏈每個
【題解】洛谷P1064[NOIP2006]金明的預算方案 有依賴的揹包問題
題目連結 我們把附件和它的主件歸到一組,其中主件為每組第一項編號為0。因為每組最多兩個附件,對於每一組,決策有以下五種(假定存在兩個附件): 1.不取這組 2.只取主件 3.取主件和附件1 4.取主件和附件2 5.取主件和附件1附件2 設 F[i,j]F[
洛谷P1064 金明的預算方案 DP揹包之依賴揹包
今天學習了揹包九講,收益頗多,總算明白了01揹包和完全揹包遍歷順序的區別,依賴揹包怎麼轉化為分組揹包,泛化物品是如何將抽象思維體現的淋漓盡致…… 並記住了一句名言:失敗並不是什麼丟人的事,從失敗中全無收穫才是。 開始正題-------金明的預算的方案 題目描述 金明今天很開心,家裡購
有依賴的揹包
Problem Description FJ is going to do some shopping, and before that, he needs some boxes to carry the different kinds of stuff he is going to buy.
【DP】計劃11.8——(樹形依賴揹包總結)&&分數規劃思想
樹形依賴揹包指的就是一類具有樹形依賴關係的揹包問題。當選一個物品的前提是選另一件物品,而這些依賴關係構成了一個樹形關係。在容量有限的情況下,然後求最大的價值,這類問題我們就稱之為樹形依賴揹包。 樹形依賴揹包問題實際上是一類分組揹包問題,我們可以將每個點的子樹看成
NOIP模擬題 2016.9.24 [貪心] [有依賴的揹包問題] [圖論] [spfa或tarjan縮點+DAGdp]
1.排座椅 (seat.pas/c/cpp) 【問題描述】 上課的時候總有一些同學和前後左右的人交頭接耳,這是令小學班主任十分頭疼的一件事情。不過,班主任小雪發現了一些有趣的現象,當同學們的座次確定下來之後,只有有限的D對同學上課時會交頭接耳。同學們在教室
揹包問題進階優雅總結【二維費用+分組+有依賴】
目錄 作者有話說 小結 小結 分析 作者有話說 本篇博文中的各類陣列都從1開始 題目裡好像混進去了什麼奇怪的東西 二維費用的揹包問題 二維費用的揹包問題是指:對於每件物品,具有兩種不同的費用,選擇這件物品必須同時付出這兩種費用
hdu 1561 (樹形dp+依賴揹包)
ACboy很喜歡玩一種戰略遊戲,在一個地圖上,有N座城堡,每座城堡都有一定的寶物,在每次遊戲中ACboy允許攻克M個城堡並獲得裡面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先
hdoj1561The more, The Better(樹形dp,依賴揹包)
題意:ACboy很喜歡玩一種戰略遊戲,在一個地圖上,有N座城堡,每座城堡都有一定的寶物,在每次遊戲中ACboy允許攻克M個城堡並獲得裡面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些
HDU 攻城堡 (依賴揹包+樹形dp)
Problem Description ACboy很喜歡玩一種戰略遊戲,在一個地圖上,有N座城堡,每座城堡都有一定的寶物,在每次遊戲中ACboy允許攻克M個城堡並獲得裡面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某一個特定的城堡。
同一個解決方案或有依賴關系的兩個項目引用同名但不同版本的DLL
web bind 節點 20px 博客 fig 朋友 ase 方案 問題描述 我們最近在使用Redis作Session的集中化,中間碰到了一個如下問題:我們有一些項目比較老,引用了NewtonJson的4.0.3.0版本的DLL,但是Redis提供的C#集成DL
基於代碼驅動:處理有依賴關系接口
gist 這樣的 equal 測試框架 return user 影響 RR 字段 數據驅動和代碼驅動的區別: 使用數據驅動好處: - 代碼復用率高。同一測試邏輯編寫一次,可以被多條測試數據復用,提高了測試代碼的復用率,同時可以提高測試腳本的編寫效率。 -
Python學習之==>有依賴關系的接口開發
接口開發 CI resp 寫入 mps 代碼 關系 and span 一、接口需求 1、登錄接口 (1)登錄成功後將session信息存入redis數據庫並設置失效時間為600秒 (2)構造返回結果的對象flask.make_response() (3)產生co
Redshift drop有依賴關系的表
csp 我們 join left span out cascade events spro 今天開發需要刪除AWS Redshift的一個歸檔表,但是直接drop發生了如下報錯,發現有其他對象依賴這個表,導致無法直接刪除,但是報錯沒有直接顯示是什麽對象依賴它,可能是有視圖,
【2017ccpc final G - Alice’s Stamps HDU - 6249 】【dp】【01揹包變形】【取k個區間使得覆蓋範圍最大】
【連結】 acm.hdu.edu.cn/showproblem.php?pid=6249 【題意】 給你m個區間,要求你選出k個區間,使得區間並的覆蓋範圍最大 1≤T≤100 1≤K≤M 1≤N,M≤2000 1≤Li≤Ri≤N 【思路】 一開始我們得出錯誤的dp轉移:
【HDU - 2546】飯卡 (dp,0-1揹包,貪心思想)
電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷餘額。如果購買一個商品之前,卡上的剩餘金額大於或等於5元,就一定可以購買成功(即使購買後卡上餘額為負),否則無法購買(即使金額足夠)。所以大家都希望儘量使卡上的餘額最少。 某天,食堂中有n種菜出售,每種菜可購買一次。已知每種菜
[ NAIPC2016 ] D Programming Team [01分數規劃 + 樹上依賴揹包]
UpCoder is looking to assign their best employees to a team tasked with designing their new and improved website, and they’re looking to you to