01背包—采药
题目链接
经典的01背包问题。
- 用dp[i][j]表示以j为容量为放入前i个物品(按 i 从小到大的顺序)的最大价值。
- 当 j 大于等于 当前物品的重量得到 转移方程 dp[i][j] = max((dp[i - 1][j - w[i]] + val[i]),dp[i - 1][j]);
- 小于的话dp[i][j] = dp[i - 1][j];
#include<bits/stdc++.h>
using namespace std;
int dp[200][200];
int w[110];//时间
int val[110];//价值
int main() {
int t,m;
cin >> t >> m;
for(int i = 1;i <= m;i++) cin >> w[i] >> val[i];
for(int i = 1;i <= m;i++) {
for(int j = 0;j <= t;j++) {
if(j >= w[i]) {
dp[i][j] = max((dp[i - 1][j - w[i]] + val[i]),dp[i - 1][j]);
}
else dp[i][j] = dp[i - 1][j];
}
}
cout << dp[m][t];
return 0;
}
也可以一维dp,要注意内循环一定是从大到小循环,要不然会覆盖
#include<bits/stdc++.h>
using namespace std;
int dp[110];
int w[110];
int val[110];
int main() {
int t,m;
cin >> t >> m;
for(int i = 1;i <= m;i++) cin >> w[i] >> val[i];
for(int i = 1;i <= m;i++) {
for(int j = t;j >= 0;j--) {
if(j >= w[i])
dp[j] = max((dp[j - w[i]] + val[i]),dp[j]);
}
}
cout << dp[t];
return 0;
}