L3-001 凑零钱 (30 分)
https://pintia.cn/problem-sets/994805046380707840/problems/994805054207279104
双向队列
判断当前剩余钱数与当前硬币的大小
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int x[N];
deque<int>st;
deque<int>id;
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>x[i];
sort(x,x+n);
int now=m;
for(int i=0;i<n;i++)
{
if(now==0) break;
if(x[i]<=now)
now-=x[i],st.push_back(x[i]),id.push_back(i);
else //(x[i]>now )
{
if(st.empty()) break;
now+=st.back();
st.pop_back();
i=id.back();
id.pop_back();
}
if(i==n-1&&now!=0&&st.size())
//运行到最后一个硬币时还没有解 但容器里存有硬币(说明存的第一个硬币有问题)
{
while( !st.empty())
{
now+=st.back();
st.pop_back();
i=id.back();
id.pop_back();
}
}
//cout<<now<<' '<<x[i]<<' '<<st.size()<<endl;
}
if(now!=0||(st.empty()&&m!=0))
{
cout<<"No Solution"<<endl;
return 0;
}
cout<<st.front();
st.pop_front();
while( !st.empty())
{
cout<<' '<<st.front();
st.pop_front();
}
return 0;
}
深搜
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int x[N],book[N],y[N],cnt=0;
int n,m,flag=0;
void dfs(int num,int t)
{
if(num==m)
{
flag=1;
if(cnt>0)
cout<<y[0];
for(int i=1; i<cnt;i++)
cout<<' '<<y[i];
}
else if(num < m)
{
for(int i=t;i<n;i++)
{
if( !flag)
{
//cout<<x[i]<<endl;
y[cnt++]=x[i];
dfs(num+x[i],i+1);
cnt--;
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>x[i];
int s=0;
for(int i=0;i<n;i++)
s+=x[i];
sort(x,x+n);
if( s>=m ) dfs(0,0);
if( !flag) cout<<"No Solution"<<endl;
return 0;
}
dfs 剪枝+后缀
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, m, flag = 0;
int x[N], y[N], cnt = 0;
int smm[N];
void dfs(int now, int sum)
{
if (sum == m)
{
flag = 1;
for (int i = 0; i < cnt; i++)
{
if(i== cnt-1) cout<<y[i]<<endl;
else cout << y[i] << ' ';
}
return;
}
else if (sum > m || now > n)
return;
for (int i = now; i < n; i++)
{
if(sum + x[i] > m) continue;
if(sum + smm[i] < m) continue;
y[cnt++] = x[i];
dfs(i + 1, sum + x[i]);
if (flag)
break;
cnt--;
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> x[i];
sort(x, x + n);
smm[n-1]=x[n-1];
for(int i=n-2;i>=0;i--)
smm[i] = smm[i+1] + x[i];
dfs(0, 0);
if (!flag)
cout << "No Solution" << endl;
return 0;
}
栈
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int x[N];
stack <int>st,id;
stack <int>tt;
int main()
{
int n,m, mm=0;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>x[i],mm+=x[i];
sort(x,x+n);
int i=0,sum=m;
if(i < n) st.push(x[i]),sum-=x[i],id.push(i++);
while( mm >m && sum && !st.empty())
{
if( i==n ||sum < x[i]) i=id.top()+1,sum+=st.top(),st.pop(),id.pop();
if(sum >= x[i] && i<n) sum-=x[i],st.push(x[i]),id.push(i),i++;
}
if(sum !=0) cout<<"No Solution"<<endl;
else {
while( !st.empty())
tt.push(st.top()),st.pop();
while( !tt.empty())
{
if(tt.size()==1) cout<<tt.top()<<endl,tt.pop();
else cout<<tt.top()<<' ',tt.pop();
}
}
return 0;
}