神奇的口袋
\(0-1\)背包计数。
状态表示:\(f(i,j)\):从前\(i\)个物品中选,体积不超过\(j\)的方案数。
边界:\(f(0,0)=1\),其余为\(0\)。
const int N=25;
int f[N][45];
int a[N];
int n;
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++) cin>>a[i];
memset(f,0,sizeof f);
f[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=40;j++)
{
f[i][j]=f[i-1][j];
if(j>=a[i]) f[i][j]+=f[i-1][j-a[i]];
}
cout<<f[n][40]<<endl;
}
//system("pause");
return 0;
}
优化至一维:
const int N=25;
int f[45];
int a[N];
int n;
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++) cin>>a[i];
memset(f,0,sizeof f);
f[0]=1;
for(int i=1;i<=n;i++)
for(int j=40;j>=a[i];j--)
f[j]+=f[j-a[i]];
cout<<f[40]<<endl;
}
//system("pause");
return 0;
}