// 给出6枚不同面值(在1到100之间)的硬币,通过 加减(注意可以减)凑出1到100的钱数,我们关心的是最少要用到几枚硬币,
// 最后求出平均值,并找出其中最大值
#include<iostream> // BFS最短路搜索
#include<stdio.h>
#include<algorithm>
#include<numeric>
using namespace std;
int euro[20],q[200],cnt[200],vis[200];
int main()
{
int cases,i;
scanf("%d",&cases);
while(cases--)
{
for(i=0;i<6;++i)
{
scanf("%d",euro+i);
euro[i+6]=-euro[i]; // 通过 加减(注意可以减)
}
fill(vis,vis+200,0);
int front=0,rear=1;
q[0]=0;
while(front<rear)
{
for(i=0;i<12;++i)
{
int u=q[front]+euro[i];
if( u>0 && u<200 && vis[u]==0 ) //因为允许减,所以一个数可以由超过100的数减另一个数得到。由于The last number is less than 100.考虑减去99的情况,故 u 的最大值取 199, 即 199-99=100
{
cnt[u]=cnt[q[front]]+1; //cnt[u]是组成币值u所需的最小货币数目
vis[u]=1;
q[rear++]=u;
}
}
front++;
}
printf("%.2f %d\n",accumulate(cnt+1,cnt+101,0)/100.0,*max_element(cnt+1,cnt+101));
}
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
//参考 poj9 3260 The Fewest Coins
#include<iostream> // 完全背包
#include<stdio.h>
#include<algorithm>
#include <numeric>
using namespace std;
int main()
{
int cases,euro[10],dp[20000],maxn;
cin>>cases;
while(cases--)
{
for(int i=1;i<=6;++i)
cin>>euro[i];
maxn=euro[5]*euro[5]+100; //上界
fill(dp,dp+maxn,-1);
dp[0]=0;
for(int i=1;i<=6;++i) // 加运算
{
for(int j=euro[i];j<=maxn;++j)
if(dp[j-euro[i]]!=-1)
{
if(dp[j]==-1)
dp[j]=dp[j-euro[i]]+1;
else
dp[j]=min(dp[j],dp[j-euro[i]]+1);
}
}
for(int i=1;i<=6;++i) // 减运算
{
for(int j=maxn-euro[i];j>0;--j) //因为是减,所以要逆序循环
if(dp[j+euro[i]]!=-1)
{
if(dp[j]==-1)
dp[j]=dp[j+euro[i]]+1;
else
dp[j]=min(dp[j],dp[j+euro[i]]+1);
}
}
printf("%.2f %d\n",accumulate(dp+1,dp+101,0)/100.0,*max_element(dp+1,dp+101));
}
return 0;
}