problemF
2016-03-29 22:20
190 查看
简单题意:一堆零钱去买东西,要求正好付钱,求最少的零钱数和最多的零钱数
解题思路:求最小零钱数的时候,要让价值大的多一些,然后用价值小的去补,求最大的零钱数 要尽量用小面值的,然后再用大面值的补;
感想:这题和背包问题有些相似,都是用贪心的算法,用价值去算
AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <vector>
#include <stack>
#include <map>
#include <queue>
#include <set>
#include <iostream>
#include <stdlib.h>
#include <cctype>
#define rep(i,s,e) for(int i = (s);i<(e);++i)
#define maxn 200000000
#define INF 1000000000
using namespace std;
int num[10];
int sum[10];
int mon[] = {0,1,5,10,50,100};
int p;
int min_num(int mon[],int num[],int p)
{
int ans = 0;
for(int i = 5;i>1;--i)
{
if(mon[i]*num[i]<=p)
{
ans += num[i];
p -= num[i]*mon[i];
}else
{
ans += p/mon[i];
p%=mon[i];
}
}
if(p<=num[1])
return p+ans;
return -1;
}
int max_num(int mon[],int num[],int sum[],int p)
{
int ans = 0;
for(int i =5;i>1;--i)
{
if(p<=sum[i-1])
continue;
else
{
int t = (p - sum[i-1])/mon[i];
if((p - sum[i-1])%mon[i]!=0)
t++;
ans += t;
p -= t*mon[i];
}
}
if(p<=num[1])
{
return ans + p;
}
return -1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&p);
int Sum = 0;
for(int i = 1;i<=5;++i)
{
scanf("%d",&num[i]);
Sum += num[i]*mon[i];
}
if(Sum < p)
{
cout<<-1<<" "<<-1<<endl;
continue;
}
sum[0] = 0;
for(int i =1;i<=5;++i)
sum [i] = sum[i-1]+num[i]*mon[i];
cout<<min_num(mon,num,p)<<" "<<max(-1,max_num(mon,num,sum,p))<<endl;
}
return 0;
}
解题思路:求最小零钱数的时候,要让价值大的多一些,然后用价值小的去补,求最大的零钱数 要尽量用小面值的,然后再用大面值的补;
感想:这题和背包问题有些相似,都是用贪心的算法,用价值去算
AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <vector>
#include <stack>
#include <map>
#include <queue>
#include <set>
#include <iostream>
#include <stdlib.h>
#include <cctype>
#define rep(i,s,e) for(int i = (s);i<(e);++i)
#define maxn 200000000
#define INF 1000000000
using namespace std;
int num[10];
int sum[10];
int mon[] = {0,1,5,10,50,100};
int p;
int min_num(int mon[],int num[],int p)
{
int ans = 0;
for(int i = 5;i>1;--i)
{
if(mon[i]*num[i]<=p)
{
ans += num[i];
p -= num[i]*mon[i];
}else
{
ans += p/mon[i];
p%=mon[i];
}
}
if(p<=num[1])
return p+ans;
return -1;
}
int max_num(int mon[],int num[],int sum[],int p)
{
int ans = 0;
for(int i =5;i>1;--i)
{
if(p<=sum[i-1])
continue;
else
{
int t = (p - sum[i-1])/mon[i];
if((p - sum[i-1])%mon[i]!=0)
t++;
ans += t;
p -= t*mon[i];
}
}
if(p<=num[1])
{
return ans + p;
}
return -1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&p);
int Sum = 0;
for(int i = 1;i<=5;++i)
{
scanf("%d",&num[i]);
Sum += num[i]*mon[i];
}
if(Sum < p)
{
cout<<-1<<" "<<-1<<endl;
continue;
}
sum[0] = 0;
for(int i =1;i<=5;++i)
sum [i] = sum[i-1]+num[i]*mon[i];
cout<<min_num(mon,num,p)<<" "<<max(-1,max_num(mon,num,sum,p))<<endl;
}
return 0;
}
相关文章推荐
- [leetcode 11] Container With Most Water
- 如何解决内存碎片
- SQL语句之order by 、group by、having、where
- UVa 272 Tex Quotes --- 水题
- Android Notification剖析
- 异步任务处理---AsyncTask
- NYOJ 题目239 月老的难题 (二分图最大匹配-匈牙利算法模板)
- 在art.dialog中加载ztree
- Go语言学习四:函数和类
- 初学者svn项目发布和下载
- 对于电梯调度的想法
- iOS GDataXMLNode的配置步骤
- 2016腾讯校园招聘模拟考试(2016.03.25)
- 2016SDAU课程练习一1008 Problem I
- 用优雅的方式解决重复点击的困扰
- Android UI模板设计---TopBar(标题栏)
- CentOS系统资源监控软件四大软件htop,top,ps,dstat
- 项目经理打分
- 排序算法之快速选择排序
- 2016腾讯校园招聘模拟考试(2016.03.25)