#include<iostream>
#include<cstring>
using namespace std;
const int N=21,M=2020;
int n,m,a[N],b[N];
int f[M];
int ma,num,last;
void dfs(int k)
{
if(k==m+1)
{
memset(f,0,sizeof f);
f[0]=1;
for(int i=1;i<=n;i++)
{
if(!b[i])
{
for(int j=n*100;j>=0;j--)
{
if(j+a[i]<=n*100&&f[j]) f[j+a[i]]=1;
}
}
}
num=0;
for(int i=1;i<=n*100;i++)
{
if(f[i]) num++;
}
ma=max(ma,num);
return;
}
for(int i=last+1;i<=n;i++)//枚举取砝码的情况(这里采用的是顺次枚举,减少耗时)
{
b[i]=1;//记录为取过了
last=i;//记录取到哪一个了
dfs(k+1);//接着往下取
b[i]=0;//回溯
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
dfs(1);
cout<<ma<<endl;
}
这里的状态方程到底是啥,不是
f[i][j]=f[i-a[i]][j-1]
嘛,但是高赞题解里面的状态转移方程是
for(int i=1;i<=n;i++)
{
if(!b[i])
{
for(int j=n*100;j>=0;j--)
{
if(j+a[i]<=n*100&&f[j]) f[j+a[i]]=1;
}
}
}
还有如果想写成二维数组,不用滚动数组该如何呢~