UVa12325 寶箱(兩種列舉方法)

2021-07-14 07:13:30 字數 1216 閱讀 1891

題目大意:

你有乙個體積為n的箱子和兩種數量無限的寶物。寶物1的體積為s1,價值為v1;寶物2的體積為s2,價值為v2。輸入均為32位帶符號的整數。你的任務是最多能裝多少價值的寶物?

方法:其實也沒那麼不好想,關鍵是要冷靜下來一步步分析,如何降低列舉的數量。首先立馬想到的肯定是性價

比高的先裝,但問題是會有剩餘空間,使得這樣的貪心策略並不是最優的。假設我們現在已經滿足s1*v2<=s2*v1,也就是說物品1價效比不會比物品2的小。那麼設最終物品1選n1件,物品2選n2件我們得到的等式就是ans=n1*v1+n2*v2。此時顯然有物品2的數量不會超過s1,(否則這s1個物品2的空間放物品1的價值為s2*v1更優),同時n2自身不會超過n/s2,對於s1<=s2的情況下顯然複雜度在sqrt(n)之下;對於s1>s2時顯然只能列舉物品1的數量了,首先由於物品1價效比高,所以我們不妨先全選了,然後再列舉要拿出多少物品1放物品2可取到最優解,那麼顯然同樣我們能拿出的物品數不會超過s2,同時總的拿出的物品數不會大於n/s1,故複雜度仍然在sqrt(n)之下。這樣問題就解決了。

本題有個有個降低列舉量的方法,即判斷s1,s2的大小關係後再進行列舉但當s1,s2都很小的則用到下面一種列舉方法:

對於寶物1和2,當所佔體積為s1*s2時,分別能夠提供的價值為s2*v1和s1*v2,我們便可以根據兩者的大小關係判斷選哪一種物品,如果s2*v1>=s1*v2,則我們可以得出寶物的數量最多為s1-1,因為如果我們選了s1件寶物2,則我們完全可以用s2件寶物1去代替,而且我們獲得價值會更大。因此每次可以列舉min(s1-1,cnt2)或者min(s2-1,cnt1)便可以得出答案。

另外書上提出了分類列舉的方法,我們可以根據s1和s2的範圍大小而採取不同的列舉方法。

#include#include#includeusing namespace std;

int main()

printf("case #%d: ",tt);

//此時s2肯定是比s1大的,但若如此n/s2都大於65536的話,說明

//不管是列舉寶物1還是寶物2的時間複雜度都是很大的!

long long value=0;

if(n/s2>=65536)// 當n/s1和n/s2都非常大的時候

else//因為資料交換的原因,s2要大些,所以n/s2要小些,此時列舉寶物2的個數

printf("%lld\n",value);

}return 0;

}

uva12325 分類列舉

由於揹包的容量n很大,所以直接列舉的方法肯定超時。所以我們可以按照價效比來分類列舉。當v1 s1較大時選擇讓第一類盡量多,反之也是。列舉的過程中以s1和s2的最小公倍數容量為乙個節點,因為如果某種的數量再增加的話,就可以用另一種來代替。所以列舉的次數最多是min s1 1,n s2 或min s2 ...

Redhat nis client兩種接入方式

redhat nis client兩種接入方式 在redhat上nis client有兩種方式接入nis伺服器 etc nsswitch.conf和system config authentication 通過 etc nsswitch.conf的方式使用者只能通過yppasswd進行修改密碼且無法...

python threading 兩種建立方式

作用 建立在thread模組之上,可以更容易地管理多個執行執行緒。通過使用執行緒,程式可以在同乙個程序空間併發地執行多個操作。threading模組建立在thread的底層特性基礎上,可以更容易地完成執行緒處理。1 呼叫函式 要使用thread,最簡單的方法就是用乙個目標函式例項化乙個thread物...