OJ-Problems-Source/POJ/3040_aiuxian.cpp

73 lines
1.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=30;
struct node
{
int x,y;//存储钱的大小和数量
bool operator<(const node c)const
{
return x>c.x;
}
}num[maxn];
int need[maxn],n,c,kj;
//need[]函数是是存储需要哪些钱币的组合
int main()
{
while(scanf("%d%d",&n,&c)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d%d",&num[i].x,&num[i].y);
sort(num,num+n);//排序是第一步
kj=0;
while(1)
{
int sum=c;
memset(need,0,sizeof(need));
for(int i=0;i<n;i++)//这个for循环是用于找出钱币的组合方法
{
if(sum>0)
{
int t=sum/num[i].x;
if(t==0)
continue;
t=min(t,num[i].y);
need[i]=t;
sum-=t*num[i].x;
}
}
if(sum>0)//如果在上面的组合中没有使sum变为0,则从小到大选择最小的面值组合,这样使面值超过的最小化
{
for(int i=n-1;i>=0;i--)
if(num[i].y&&num[i].x>=sum)
{
sum=0;
need[i]++;
break;
}
}
if(sum>0)//如果组合不能达到c怎么说明搜索结束
break;
int cc=2e9;
for(int i=n-1;i>=0;i--)//找出这个组合成的面值中最小的数量,同时减去它们。
{
if(need[i])
{
cc=min(cc,num[i].y/need[i]);
}
}
kj+=cc;
for(int i=0;i<n;i++)
if(need[i])
{
num[i].y-=cc*need[i];
}
}
printf("%d\n",kj);
}
return 0;
}