从01背包到完全背包就是一件非常简单的事情,这里以P1616 疯狂的采药做例子,来讲一讲如何从01背包迁移到完全背包。
还记得我们上次在从记忆化搜索到0/1背包里的东西么?
但是,我们要注意,如果我们正着dp,也就是从$ti = 0$dp到$ti = n$,这样有可能会重复,也就是比如我们$dp[6]$取了第$x$件物品,到后面如果转移到$ti = 6$时($dp[6] + v[x]$),我们就会重复计算$v[x]$,从$ti = n$dp到$ti = 0$就不会出现这个问题($ti$小的不会转移到$ti$大的)
然而,我们现在要的就是要重复,所以我们直接从$t_i = 0$ dp到$t_i = T$就好啦。
一维dp/$76.96MB$/$126ms$
数据比较大,记得开long long
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using namespace std;
long long n,T,t[MAXN],v[MAXN],dp[MAXT];
int main(){
cin>>T>>n;
for(int i = 1;i <= n;i++)
cin>>t[i]>>v[i];
for(int x = 1;x <= n;x++)
for(int ti = t[x];ti <= T;ti++)
dp[ti] = max((dp[ti-t[x]]+v[x]),dp[ti]);
cout<<dp[T]<<endl;
return 0;
}