$01$背包,路径记录,贪心。
可以将物品从大到小排序之后进行背包,同时记录路径。
#include<map> #include<set> #include<ctime> #include<cmath> #include<queue> #include<string> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; int n,m,a[10010]; int f[10010][110],r[10010][110],c[10010][110]; bool cmp(int a,int b) { return a>b; } int main() { scanf("%d%d",&n,&m); memset(f,0,sizeof f); memset(r,0,sizeof r); f[0][0]=1; for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++) { for(int j=0;j<=m;j++) { f[i][j]=f[i-1][j]; r[i][j]=r[i-1][j]; } for(int j=0;j<=m;j++) { if(f[i-1][j]==0) continue; if(j+a[i]>m) continue; f[i][j+a[i]]=1; r[i][j+a[i]]=i; } } if(f[n][m]==0) printf("No Solution "); else { int x=n,y=m; vector<int>ans; while(1) { if(x==0) break; if(r[x][y]!=x) x=r[x][y]; else { ans.push_back(a[x]); int t=x; x=r[x-1][y-a[x]]; y=y-a[t]; } } sort(ans.begin(),ans.end()); for(int i=0;i<ans.size();i++) { printf("%d",ans[i]); if(i<ans.size()-1) printf(" "); else printf(" "); } } return 0; }