L3-001 凑零钱 (天梯赛)

考虑01背包 因为要求刚好凑满 所以转移的时候要判断一下

最后就是要求输出字典序最小的 首先保证能凑到 再者序列长度尽量长 最后保障小

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=1e4+5;
int n,m,cnt;
int a[maxn],dp[maxn],vis[maxn][105],ans[maxn];
void print();
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<maxn;i++)dp[i]=-1;
	sort(a+1,a+1+n);
	dp[0]=0;
	for(int i=1;i<=n;i++)
	for(int j=m;j>=a[i];j--)
	if(dp[j-a[i]]!=-1)
		if(dp[j-a[i]]+1>=dp[j])
		dp[j]=dp[j-a[i]]+1,vis[i][j]=1;
	if(dp[m]!=-1)
	print();
	else printf("No Solution");
     return 0;
}
void print(){
	int j=m;
	for(int i=n;i>=1;i--)
	if(vis[i][j])
	j-=a[i],ans[++cnt]=a[i];
	cout<<ans[cnt];
	for(int i=cnt-1;i>=1;i--)
	cout<<" "<<ans[i];
}
posted @ 2022-04-18 14:26  wzx_believer  阅读(89)  评论(0)    收藏  举报