专栏文章

题解:P1048 [NOIP2005 普及组] 采药

P1048题解参与者 4已保存评论 4

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
4 条
当前快照
1 份
快照标识符
@miqidh5i
此快照首次捕获于
2025/12/04 05:17
3 个月前
此快照最后确认于
2025/12/04 05:17
3 个月前
查看原文

思路

经典 01背包 问题。观察到题目中含有「时间」与「价值」字样,考虑使用 背包 求解。
定义 wiw_i 表示采药时间,cic_i 表示药的价值和数组 fi,vf_{i,v},表示采前 ii 株草药花费 vv 个单位时间获得的最大价值。显见,对于前 ii 株草药,可以选择采与不采第 ii 株草药,采后会花费 wiw_i 的时间。根据上文,我们可以列出转移方程:
fi,vmax(fi1,v,fi1,vwi+ci)f_{i,v} \gets \max(f_{i-1,v},f_{i-1,v-w_i} + c_i)
其中,fi1,vf_{i-1,v} 表示不采这株草药的价值,fi1,vwi+cif_{i-1,v-w_i} + c_i 表示采这株草药的价值,我们要取二者最大值。
显见最后输出结果为 fM,Tf_{M,T}
时间复杂度为 O(TM)O(TM)

实现

CPP
# include <iostream>
using namespace std;
int w[1145],c[1145],f[1145][1145];
int main(){
	int n,m; cin >> m >> n;
	for (int i = 1;i <= n;i++) cin >> w[i] >> c[i];
	for (int i = 1;i <= n;i++){
		for (int v = m;v > 0;v--){
			if (w[i] <= v) f[i][v] = max(f[i-1][v],f[i-1][v-w[i]]+c[i]);
			else f[i][v] = f[i-1][v];
		}
	}cout << f[n][m];
	return 0;
}

评论

4 条评论,欢迎与作者交流。

正在加载评论...