从01背包到完全背包

从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
#include<bits/stdc++.h>
#define MAXN 10005
#define MAXT 10000005
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;
}

文章作者: Tim
文章链接: http://itstim.xyz/AllPacket/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Tim's Blog
支付宝恰饭打赏
微信恰饭打赏