PAT L3-001 凑零钱
01背包题目
写的时候竟然发现自己忘了怎么写01背包了,跪了
花了10分钟复习一下,发现其实还是很简单的
但这道题目要求记录轨迹,wa了好几发在轨迹上才过
dp数组可以复用,但要注意j要从小到大,确保j-w[i]用到的是i-1的数据
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 2e5;
int n,m,k;
int w[N],dp[N],ans[N],pre[N];
int main() {
fill(dp,dp+N,INT_MIN);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
sort(w+1,w+1+n);
dp[0]=0;
for(int i=1;i<=n;i++) {
for(int j=m;j>=w[i];j--) {
if(dp[j]<=dp[j-w[i]]+1) {
dp[j]=dp[j-w[i]]+1;
ans[j]=w[i];
pre[j]=j-w[i];
}
}
}
if(dp[m]<=0) cout<<"No Solution"<<endl;
else {
vector<int> ret;
while(ans[m]){
ret.push_back(ans[m]);
m=pre[m];
}
for(auto it=ret.rbegin();it!=ret.rend();it++) {
if(it!=ret.rbegin()) cout<<' ';
cout<<*it;
}
}
}