# Dynamic Programming# Knapsack Problem

c147 - 105北二5搬家規劃問題

🔗 前往 ZeroJudge 原題

題目描述

題目要求在給定物品重量和需求度,以及載重量限制下,計算最多可搬運的總需求度。這是一個典型的 0/1 背包問題變形。

解題思路

本題使用動態規劃解決。ans[j] 表示在載重量為 j 時,可以獲得的最大需求度。我們遍歷每個物品,對於每個物品,我們考慮是否將其放入背包。如果放入,則更新 ans[j + 物品重量] 的值,使其等於 ans[j] + 物品需求度 和原來的 ans[j + 物品重量] 中的最大值。最終,ans 陣列中的最大值即為最多可搬運的總需求度。

複雜度分析

  • 時間複雜度: O(n * L),其中 n 是物品數量,L 是載重量。
  • 空間複雜度: O(L),用於儲存 ans 陣列。

程式碼

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define max( x, y )  ( ((x)>(y)) ? (x):(y) )
#include <stdio.h>
inline int read(){
	int a(0);
	char c('0');
	while(c>='0'){
		a=(a<<3)+(a<<1)+c-'0';
		c=getchar_unlocked();
	}
	return a;
}
inline void write(int x) {
	int stk[9],*ptr(&stk[0]);
	while(x){*ptr=x%10;x/=10;++ptr;}
	while(--ptr>=(&stk[0])){putchar_unlocked(*ptr+'0');}
}
int a[100000],it=0,ans[1000001];
int main(){
	while(a[it]=read())++it;
	int n=(it-1)/2,mx=a[it-1],ac=0;
	for(int i=0;i<n;++i)
		for(int j=mx-a[i];j>=0;--j)
			if(ans[j]||j==0){
				int jai=j+a[i];
				ans[jai]=max(ans[jai],ans[j]+a[i+n]);
				ac=max(ans[jai],ac);
			}
	write(ac);
}

Discussion