$\huge \color{orange}{成魔之路->}$ $\huge \color{purple}{算法提高课题解}$
完全背包求方案数结论: $f[i][j]=f[i-1][j]+f[i][j-v[i]]$
推导过程:
$因为,f[i][j]=f[i-1][j]+f[i-1][j-v]+f[i-1][j-2v]+…+f[i-1][j-sv]$
$\ \ \ \ \ \ \ \ \ \ f[i][j-v]=\ \ \ \ \ \ \ \ \ \ \ \ \ \ f[i-1][j-v]+f[i-1][j-2v]+…+f[i-1][j-sv]$
$所以,f[i][j]=f[i-1][j]+f[i][j-v]$
思路:
-
$1. 状态表示$
$集合:从前\ i\ 个物品中选,体积等于\ j\ 的方案$
$属性:Count$ -
$2. 状态转移$
$f[i][j]=f[i-1][j]+f[i][j-v[i]]$ -
$3. 滚动数组$
$由于\ f[i][j]\ 只需用到当前层和上一层,则结论可转化为:f[j]=f[j]+f[j-v[i]]$
完整代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n;
int f[N];
int v[4]={10,20,50,100};
int main()
{
cin>>n;
f[0]=1;
for(int i=0;i<4;i++)
for(int j=v[i];j<=n;j++) //保证了 f[j - v[i]] 是 f[i][j - v[i]]
f[j]+=f[j-v[i]];
cout<<f[n]<<endl;
return 0;
}