Codeforces Round #583 (Div. 1 + Div. 2)A. Optimal Currency Exchange (dfs)
https://codeforces.com/contest/1214/problem/A
安德鲁剩n卢布,想换成欧元和美钞。一美元的价格是d卢布,一欧元需要e卢布。
存在以下美元钞票:1、2、5、10、20、50、100,以及以下欧元钞票— 5、10、20、50、100、200。安德鲁可以购买任何组合的钞票(也可以同一种钞票换取很多),他的目标是将兑换后他将拥有的卢布总数最小化。
给定整数n、e和d,找出安德鲁在购买美元和欧元钞票后能得到的最小卢布数。
input
100
60
70
output
40
input
410
55
70
output
5
input
600
60
70
output
0
误打误撞看漏了一个条件,以为是dfs
虽然wa了之后才发现写假了,但是也是很开心哇
终于会dfs了,is good!
//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cstdio>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<deque>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=500200;
const int M=5002;
const int mod=998244353;
LL a[N],b[N];
//int h[N],w[N],e[N],ne[N],dist[N],idx;
int f[M][M];
bool vis[N],st[N];
int dx[]={-1,0,0,1,-1,-1,1,1},dy[]={0,1,-1,0,1,-1,-1,1};
LL minn=0,maxn=0;
int n,d,e;
void dfs(LL sum,LL idx)
{
if(idx==14)
{
if(sum<=n&&sum>=0) maxn=max(maxn,sum);
return ;
}
if(sum>n) return ;
dfs(sum+a[idx],idx+1);
dfs(sum,idx+1);
}
int main()
{
//cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int T=1;
//cin>>T;
while(T--)
{
map<int,int> mp;
mp[1]=1; mp[2]=2; mp[3]=5; mp[4]=10; mp[5]=20; mp[6]=50; mp[7]=100;
mp[8]=5; mp[9]=10; mp[10]=20; mp[11]=50; mp[12]=100; mp[13]=200;
cin>>n>>d>>e;
for(int i=1;i<=7;i++)
{
a[i]=mp[i]*d;
minn+=a[i];
}
for(int i=8;i<=13;i++)
{
a[i]=mp[i]*e;
minn+=a[i];
}
sort(a+1,a+1+13);
//for(int i=1;i<=13;i++) cout<<a[i]<<" ";
dfs(0,1);
cout<<n-maxn<<endl;
}
return 0;
}
此题正解
如下所示
//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cstdio>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<deque>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=500200;
const int M=5002;
const int mod=998244353;
LL a[N],b[N];
//int h[N],w[N],e[N],ne[N],dist[N],idx;
int f[M][M];
bool vis[N],st[N];
int dx[]={-1,0,0,1,-1,-1,1,1},dy[]={0,1,-1,0,1,-1,-1,1};
LL minn=0,maxn=0;
int n,d,e;
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int T=1;
//cin>>T;
while(T--)
{
cin>>n>>d>>e;
int minn=n%d;
//cout<<minn<<endl;
//因为有一张是1块钱的,所以可以初步认定最小的就是n换1之后换不了的美元
//美元后面的都是1的倍数,所以只用上第一个其实就可以了
for(int i=0;;i++)
{
if(n>=0)
{
//1, 2, 5, 10, 20, 50, 100
minn=min(minn,n%d);
//5 ,10, 20, 50, 100, 200
//欧元都是5的倍数,所以只需要判断能否凑出x个d以及y*5个e==n就行了
n-=e*5;
}
else break;
}
cout<<minn<<endl;
}
return 0;
}