01背包,四维dp
前i个物品中选j个,mod k,余数为l
#include<iostream>
using namespace std;
typedef long long ll;
const int N=105,mod=998244353;
int f[N][N][N][N];//前i个物品中选j个,mod k,余数为l
int a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)f[0][0][i][0]=1;//初始化
for(int i=1;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
for(int k=1;k<=n;k++)
{
for(int l=0;l<n;l++)
{
f[i][j][k][l]=(f[i][j][k][l]+f[i-1][j][k][l])%mod;//i个物品不选
if(j>=1)
f[i][j][k][l]=(f[i][j][k][l]+f[i-1][j-1][k][(l-a[i]%k+k)%k])%mod;//i选
}
}
}
}
ll ans=0;
for(int i=1;i<=n;i++)
{
ans=(ans+f[n][i][i][0])%mod;
}
cout<<ans<<endl;
return 0;
}
其实可以把dp第三维去掉
可以滚动优化掉第一维,这样写也是便于看hh
我说的是第三维,当然滚掉第一维自然也可以
ok