SPOJ HKNAP 部分貪心

2021-08-07 21:25:15 字數 2103 閱讀 1644

有s個袋子,袋子容量為y,合併兩個袋子花費為c,雕像有n種。接下來n行每行有乙個w和乙個v,分別代表雕像的重量和體積。問所帶的雕像重量-袋子花費最多可以是多少。

這道題是出現在部分貪心這篇oi**中的。儘管主題是部分貪心,但實際上就是揹包的空間優化。不過不是從演算法上進行優化,而是從題目的資訊上進行優化。

首先的話,根據題目體積只有1-18這18種情況,那麼我們就只保留對於每個體積重量最大的元素就可以了。然後我們求出來價效比最高的元素,作為主要填充物。

我們假設主要填充物的w為wi,v為vi。我們可以分析一下,可以發現其他填充物的數量一定是小於vi的。因為如果其他填充物的數量》=vi,那麼一定可以抽出來v[i]*vi的空間,這塊空間顯而易見要填充價效比最高的元素,因此可以得到其他每種填充物數量一定 < vi。這樣的話,我們可以得到填充其他填充物的容量上限lim=vi*18(為了方便,我們把這個上限設定的大一點,允許裝vi個主要填充物)。

上述分析是第一步,我們可以根據這一步的結果求出來不填充主要填充物的時候的最大收益。其實就是乙個簡單的可重複選擇元素的揹包問題。

求出來這個以後,我們要考慮一下合併的問題。合併的揹包數量不超過lim。我們可以假設揹包的體積為1(最小值)。如果我們合併之後裝的體積》lim,那麼就代表一定有一部分空間充滿了主要填充物(應為其他物品最多只能裝到lim)。既然這一部分裝的是主要填充物,那麼這一部分和剩餘部分是沒有必要合併的。

可能有人會有疑問,有沒有可能存在不能拆分的情況,比如2個容量3的揹包,3個體積2的雕像,如果不合併,就只能裝2個,只有合併了才能裝3個。我們可以再分析一下,就會發現這個擔心是多餘的。因為我們組成的揹包容量為y*(lim+x),而lim=vi*18。這樣的話,就會發現y*(vi*18+x),我們很容易就能分離出乙個vi*xx的揹包,使得總容量為y*(vi*(18-xx)+x) < y*lim。

這樣的話,我們就可以計算出合併1-lim種揹包的最大收益。這時候需要再進行一次揹包計算。這個子問題是,我們有s個揹包,我們有lim種揹包,問我們能獲得的最大收益是多少。進行一下揹包計算,輸出dp[s]即可。

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define up(i,l,h) for(int i=l;i#define down(i,h,l) for(int i=h-1;i>=l;i--)

#define w(a) while(a)

#define mem(a,b) memset(a,b,sizeof(a))

#define ll long long

#define inf 0x3f3f3f3f3f3f3f3f

#define maxn 1050

#define mod 1000000007

#define eps 1e-3

#define int ll

using

namespace

std;

int w[20];

int dp[maxn],ans[maxn];

int lim,n,s,y,c,wi,vi;

int getw(int x)

main()

wi=w[1],vi=1;

up(i,2,19) if(w[i]*vi>i*wi) wi=w[i],vi=i;

lim=vi*18;

up(i,1,19) up(j,0,lim+1) if(j-i>=0) dp[j]=max(dp[j],dp[j-i]+w[i]);

up(i,0,lim+1) dp[i]=max(dp[i],dp[i-1]);

up(i,1,lim+1) ans[i]=getw(i)-c*(i-1);

mem(dp,0);

up(i,0,lim+1) up(j,0,s+1) if(j-i>=0) dp[j]=max(dp[j],dp[j-i]+ans[i]);

printf("%lld\n",dp[s]);

}}

部分揹包問題(貪心基礎)

有n個物體,第i個物體重量為w i 價值為v i 在總重量不超過c的情況下讓總價值盡量高.取乙個物品必須全取,價值和重量按比例計算 分析 貪心策略 優先拿 價值除以重量的值 最大的,重量和小於等於c include include include using namespace std struct...

貪心 部分揹包問題

阿里巴巴走進了裝滿寶藏的藏寶洞。藏寶洞裡面有 n n 100 堆金幣,第 i 堆金幣的總重量和總價值分別是 mi,vi 1 mi,vi 100 阿里巴巴有乙個承重量為 t t 1000 的揹包,但並沒辦法將全部的金幣都裝進去。他想裝走盡可能多價值的金幣。所有金幣都可以隨意分割,分割完的金幣重量價值比...

貪心法求解部分揹包問題

揹包問題 給定乙個載重為m的揹包,及n個質量為wi 價值為pi的物體,1 i n,要求把物體裝滿揹包,且使得揹包內的物體價值最大。假設 xi是物體i被裝入揹包的部分,0 xi 1。當xi 0時,表示物體i沒有被裝入揹包 當xi 1時,表示物體i被全部裝入揹包 當xi處於0 1之間,表示物體i的一部分...