贪心(非区间问题的复习)

poj3040试题 此题的思路还是能想到的 实现起来代码略长

我参考了他人的结题报告:https://blog.csdn.net/zwj1452267376/article/details/50429521

不废话 上代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define Max 30
using namespace std;
typedef struct money{
int value;
int number;
}m;
m coin[Max];
bool cmp(m a,m b)
{
return a.value>b.value;
}
int n,c;
int main()
{
int i,j,k;
scanf("%d %d",&n,&c);
//输入 
for( i=0;i<n;i++)
{
scanf("%d %d",&coin[i].value,&coin[i].number);
}

//对面值大于等于c的 直接取走
int cnt=0;
sort(coin,coin+n,cmp);//按面值从大到小排序 
for(i=0;i<n;i++){
if(coin[i].value>=c)
{
cnt+=coin[i].number;
coin[i].number=0;
}


//下面只是剩下面值小于c的了
int use[Max];//标记使用的大小 
while(1){
memset(use,0,sizeof(use));
int mm=c;
//下面还是往大了挑 
for(i=0;i<n;i++){
if(!coin[i].number) continue;//没有就算了 
if(coin[i].number>0){
int k=mm/coin[i].value;
int mi=min(k,coin[i].number);
mm-=mi*coin[i].value;//第一轮挑选
coin[i].number=coin[i].number-mi;
if(mm<=0)
{
cnt++;
break;//挑选成功

 
}
}
if(mm>0)//必须挑选第二次//从小到大拿 
{
for(i=n-1;i>=0;i--)
{
if(!coin[i].number) continue;
for(k=1;k<=coin[i].number;k++)
{
coin[i].number--;//硬币减1 
mm-=k*coin[i].value;
if(mm<=0)
{
cnt++;
break;//够了 不用挑选了 
}
}
if(mm<=0) break;

}
if(mm>0) break;//数轮挑选都失败了 只能跳出 
 
}
printf("%d\n",cnt);
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值