传送门 | 难度 |
---|---|
https://www.luogu.com.cn/problem/P1616 | 普及- |
这是一道完全背包板子题。
符号说明
- t:所需时间数组
- v:价值数组
- dp:原始动态规划数组
- i:第i种药
- j:可用时间j
- f:优化空间复杂度后的动态规划数组
状态转移方程
- 易知原始状态转移方程
dp[i][j]=max{dp[i-1][j-k*t[i]]+k*v[i]|0<=k<=T/t[i]}
- 优化时间复杂度后的状态转移方程
dp[i][j]=max{dp[i-1][j],dp[i][j-t[i]]+v[i]}
- 优化空间复杂度后的状态转移方程
f[j]=max{f[j],f[j-t[i]]+v[i]}
AC代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int T,M;// 可用总时间T,草药数M
int t[10005];//用时
int v[10005];//价值
int f[100005];//动态规划数组
int main() {
while (scanf("%d%d", &T, &M) != EOF) {
for (int i = 0; i < M; ++i) {
scanf("%d%d", &t[i], &v[i]);
}
for (int i = 0; i <= T; ++i) //初始化动态规划数组
f[i] = 0;
for(int i = 0; i < M; ++i)
for (int j = t[i]; j <= T; ++j) {
f[j] = max(f[j], f[j - t[i]] + v[i]);
}
printf("%d\n", f[T]);
}
return 0;
}