01揹包是是乙個普通的動態規劃入門問題:
一共有n個物品, 第i個物品的體積為v[i];
有乙個揹包容量為m,現在我要挑選一些物品放入這個揹包
我現在知道在總體積不超過揹包容量的情況下,他一共有多少種放法(總體積為0也算一種放法)。
1 <= n <= 30, 1 <= m , v[i]<= 1e9
這就是乙個很簡單的01揹包問題,我可以告訴你核心**怎麼寫:
很簡單吧,但是……,你試一試吧。
輸入有多組,每一組第一行是n和m接下來第二行到第n+1行,第i+1行表示v[i]。
輸出每個樣例的方案數,每個答案佔據一行。示例1
3 10124
8解析:
#include using namespace std;
typedef long long ll;
int main()
ll ans = 0;
for (int i = 0; i < (1 << n); i++)
cout << ans << endl;
}return 0;
}
但是n的大小為30,列舉子集的話也是會超時的 (2 ^ 30) 可是接近 1e9 的數量級別
首先我們將前 n/2 個物品進行子集的列舉,將其所有能達到重量量放入陣列中arr中
非遞減排序後,我們再列舉剩下 n - n/2個物品的子集.
對於每乙個子集計算其放入的重量和sum.用總容量w - sum.
得到我們還能放入多少重量的物品 res = w - sum
於是我們去前 n / 2個物品的子集和陣列 arr 中二分尋找
最後乙個小於等於 res 的元素的位置 pos (可用upper_bound求解).
於是[0,pos] <= res 這些都是可滿足條件的解,累加即可.
**:
#includeusing namespace std;
typedef long long ll;
vectorarr;
ll val[35];
int main()
{ int n;ll m;
while(~scanf("%d%lld",&n,&m))
{arr.clear();
for(int i=0;i>1,n2 = n - (n>>1);
//printf("%d %d\n",n1,n2);
for(int i=0;i
中南林業大學第十一屆程式設計競賽
theme 有很多砝碼,質量為w的0次方 1次方 n次方,每個砝碼都只有乙個。有乙個天平,給定乙個重物重量為m,問能否通過放置重物和砝碼使得天平平衡,重物和砝碼可以放在一邊或兩邊。2 w 10 9,1 m 10 9 solution 如果砝碼只能放在一邊,則若m w i,或1 w 0 w 1.w i...
東北林業大學OJ題目1
百步穿楊 problem 796 time limit 1000ms memory limit 65536k description 時維九月,序屬三秋,遼軍大舉進攻帽兒山,戰場上兩軍正交鋒.遼軍統帥是名噪一時的耶律洪豬,而帽兒山方則是派出了傳統武將 松樹葉子。雙方經過協商,約定在十一月八日正午十分...
A喝酒 北京林業大學校賽
王大釘喜歡喝酒,存貨都喝完了,他就去樓下買,正好樓下的商店為了響應學校的 acm 校賽推出了優惠活動 凡是在本店買的啤酒,喝完以後 3 3 個空瓶可以換一瓶,4 4 個瓶蓋也可以換一瓶酒。王大釘覺得太合算了,決定多買,現在他手裡的錢可以買 n n 瓶酒,但是他算不出來,通過活動兌換他一共可以喝到多少...