成魔之路−> 算法提高课题解
完全背包求方案数结论: 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;
typedef long long LL;
const int N = 3010;
int n,m;
LL f[N];
int main()
{
cin>>n>>m;
f[0]=1;
for(int i=0;i<n;i++)
{
int v;
cin>>v;
for(int j=v;j<=m;j++) f[j]+=f[j-v];
}
cout<<f[m]<<endl;
return 0;
}