前言
会考虑如何证明
1. 不超过
1.1 方案数
对于方案数,我们需要先初始化 f ( 0 ) [ i ] = 1 f(0)[i] = 1 f(0)[i]=1 然后从 v v v到 m m m的倒序转移即可
for(int i=0;i<=m;i++)
f[i] =1 ;
for(int i=1;i<=n;i++)
for(int j = m;j>=v;j -- )
f[j] +=f[j-v];
1.2 最值问题
最基础也是最先学的一类01背包问题
全部初始化为 0 0 0对于每次输入,倒序状态转移
for(int i=1;i<=n;i++)
for(int j = m;j>=v;j -- )
f[j] = max(f[j],f[j-v]+w);
2. 恰好
2.1 方案数
除了 f[0][0] = 1
之外,所有的都设置为
0
0
0
并且我们倒序降维的状态转移
f[0][0] = 1;
for(int i=1;i<=n;i++)
for(int j =m;j>=v;j -- )
f[j] = max(f[j],f[j-v[i]])
2.2 最值问题
除了f[0][0] =0
之外其余都是-INF
(最大价值是
−
-
− 最小就是
+
+
+)
然后照样 倒序状态转移
memset(f,0x3f,sizeof f)
f[0] = 0 ;
for(int i=1;i<=n;i++)
for(int j = m;j>=v;j -- )
f[j] = max(f[j],f[j-v]+w);
3. 至少是
至少的情况 要么从m->0 要么就是从0->m
3.1 方案数
除了 f [ 0 ] [ 0 ] = 1 f[0][0] = 1 f[0][0]=1之外其他全部为 0 0 0
然后我们倒序状态转移
f[0] = 1;
for(int i=1;i<=n;i++)
for(int j = m;j>=0;j -- )
f[j]+=f[j-v ? 0];
3.2 最值问题
除了
f
[
0
]
=
0
f[0]=0
f[0]=0外,其他全部是 -INF
只会求最小值
然后我们倒序状态转移
memset(f,-0x3f,sizeof f);
f[0]=0;
for(int i=1;i<=n;i++)
for(int j = m;j>=0;j -- )
f[j] = min(f[j],f[j-v ? 0 ]+w);