# Dynamic Programming# Greedy# Array

a587 - 祖靈好孝順 ˋˇˊ

🔗 前往 ZeroJudge 原題

題目描述

題目描述了祖靈在玩遊戲時獲得了許多寶物,每個寶物都有重量和價值。祖靈的背包有重量限制,要求計算祖靈最多可以帶回的寶物總價值。

解題思路

這題是一個典型的 0/1 背包問題。可以使用動態規劃來解決。b[j] 表示背包容量為 j 時,可以獲得的最大價值。對於每個物品,我們考慮是否將其放入背包。如果放入,則背包容量減少物品的重量,價值增加物品的價值。我們比較放入和不放入兩種情況下的最大價值,並選擇較大的值。

程式碼中,a[i][0] 儲存第 i 個物品的重量,a[i][1] 儲存第 i 個物品的價值。b[w+1] 是一個陣列,用於儲存不同背包容量下的最大價值。max 變數用於追蹤目前找到的最大價值。

程式碼使用雙重迴圈來遍歷所有物品和所有可能的背包容量。外層迴圈遍歷物品,內層迴圈遍歷背包容量。對於每個物品和背包容量,程式碼計算將該物品放入背包後的價值,並更新 b 陣列。

複雜度分析

  • 時間複雜度: O(N * W),其中 N 是物品數量,W 是背包的重量限制。
  • 空間複雜度: O(W),其中 W 是背包的重量限制。

程式碼

#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")
#include <stdio.h>
//#define getchar_unlocked getchar
//#define putchar_unlocked putchar
int a[101][2];
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) {
	if(x==0){
		putchar_unlocked(48);
		putchar_unlocked(10);
		return;
	}
	int stk[9],*ptr(&stk[0]);
	while(x){*ptr=x%10;x/=10;++ptr;}
	while(--ptr>=(&stk[0])){putchar_unlocked(*ptr+'0');}
	putchar_unlocked(10);
}
int main(){
	int N,w;
	while(N=read()){
		for(int i(0);i<N;++i){
			a[i][0]=read();
			a[i][1]=read();
		}
		w=read();
		int b[w+1]={0},max(0);
		for(int i(0);i<N;++i)
			for(int j(a[i][0]),jai(0),bjai;j<=w;++j,++jai){
				bjai=b[j]+a[i][1];
				if(b[jai]<bjai){
					b[jai]=bjai;
					(max<b[jai])&&(max=b[jai]);
				}
			}
		write(max);
	}
}

Discussion