①vis数组
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int dp[111],ans[11111];
bool vis[11111][111];
int a[11111];
int N,M,k=0;
void print()
{
int j=M;
for(int i=N;i>=1;i--)
{
if(vis[i][j]==true)
{
j-=a[i];
ans[k++]=a[i];
}
}
for(int i=k-1;i>=0;i--)
{
cout<<ans[i];
if(i!=0)cout<<" ";
else cout<<endl;
}
}
int main()
{
cin>>N>>M;
for(int i=1;i<=N;i++)
{
cin>>a[i];
}
memset(dp,-inf,sizeof(dp));//一定要装满而不是尽可能装满,所以初始值为-inf
memset(vis,false,sizeof(vis));
sort(a+1,a+N+1);//保证输出从小到大
dp[0]=0;//装满才有效
for(int i=1;i<=N;i++)
{
for(int j=M;j>=a[i];j--)
{
if(dp[j-a[i]]+1>=dp[j])
{
dp[j]=dp[j-a[i]]+1;//一维滚动数组优化 ,记录需要几种(个)硬币
vis[i][j]=true;
}
else vis[i][j]=false;
}
//cout<<pre[i]<<endl;
}
if(dp[M]>0)
print();
else
cout<<"No Solution"<<endl;
}
②pre数组,这题过了,但可能做其他类型背包有bug
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int dp[111],ans[11111],pre[111];
int a[11111];
int N,M,k=0;
void print()
{
for(int j=M;j>0;j-=a[pre[j]])
{
if(pre[j]) ans[k++]=a[pre[j]];
}
for(int i=k-1;i>=0;i--)
{
cout<<ans[i];
if(i!=0)cout<<" ";
else cout<<endl;
}
}
int main()
{
cin>>N>>M;
for(int i=1;i<=N;i++)
{
cin>>a[i];
}
memset(dp,-inf,sizeof(dp));//一定要装满而不是尽可能装满,所以初始值为-inf
sort(a+1,a+N+1);//保证输出从小到大
dp[0]=0;//装满才有效
for(int i=1;i<=N;i++)
{
for(int j=M;j>=a[i];j--)
{
if(dp[j-a[i]]+1>=dp[j])
{
dp[j]=dp[j-a[i]]+1;//一维滚动数组优化 ,记录需要几种(个)硬币
pre[j]=i;//有几种记录方式
}
}
}
if(dp[M]>0)
print();
else
cout<<"No Solution"<<endl;
}