有一些问题想要请教大佬
查看原帖
有一些问题想要请教大佬
559529
SurftheMoon楼主2022/3/1 18:07
#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;
                }
            }
        }

还有如果想写成二维数组,不用滚动数组该如何呢~

2022/3/1 18:07
加载中...