首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【POJ】3040 - Allowance(贪心)

【POJ】3040 - Allowance(贪心)

作者头像
FishWang
发布2025-08-26 19:55:05
发布2025-08-26 19:55:05
8300
代码可运行
举报
运行总次数:0
代码可运行

点击打开题目

Allowance

Time Limit: 1000MS

Memory Limit: 65536K

Total Submissions: 2940

Accepted: 1189

Description

As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins).Using the given set of coins, he would like to pay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week.Please help him ompute the maximum number of weeks he can pay Bessie.

Input

* Line 1: Two space-separated integers: N and C * Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.

Output

* Line 1: A single integer that is the number of weeks Farmer John can pay Bessie at least C allowance

Sample Input

代码语言:javascript
代码运行次数:0
运行
复制
3 6
10 1
1 100
5 120

Sample Output

代码语言:javascript
代码运行次数:0
运行
复制
111

Hint

INPUT DETAILS: FJ would like to pay Bessie 6 cents per week. He has 100 1-cent coins,120 5-cent coins, and 1 10-cent coin. OUTPUT DETAILS: FJ can overpay Bessie with the one 10-cent coin for 1 week, then pay Bessie two 5-cent coins for 10 weeks and then pay Bessie one 1-cent coin and one 5-cent coin for 100 weeks.

Source

USACO 2005 October Silver

这个贪心题真心好,但是也挺麻烦。

如果钱数大于等于C的,那么就直接发出。如果小于 c 的,则从大往小拿,可以等于但是不能大于 c ,如果等于 c 就发出去,如果到最后也没有等于 c 的,再从小往大拿,能发就发,如果反向滚回来还不能发出去的话,剩下的钱就不能发了,直接退出就行。(实力滚键盘)

代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
	__int64 v,m;
}coin[22];
bool cmp(node a,node b)
{
	return a.v > b.v;
}
int main()
{
	__int64 n,c;
	__int64 ans;
	while (~scanf ("%I64d %I64d",&n,&c))
	{
		for (int i = 0 ; i < n ; i++)
			scanf ("%I64d %I64d",&coin[i].v,&coin[i].m);
		sort (coin , coin + n , cmp);
		ans = 0;
		bool flag = true;		//是否能继续拿 
		for (int i = 0 ; i < n ; i++)
		{
			if (coin[i].v >= c)
				ans += coin[i].m;
			else		//首先从大往小拿 
			{
				while (coin[i].m)
				{
					int t = 0;		//已经拿的钱数 
					for (int j = i ; j < n ; j++)
					{
						if (!coin[j].m)		//没钱了就跳过 
							continue;
						while (coin[j].m && t < c)
						{
							t += coin[j].v;
							coin[j].m--;
						}
						if (t == c)		//如果正好发完就发了 
						{
							ans++;
							break;
						}
						else		//否则就再往下搜 
						{
							t -= coin[j].v;
							coin[j].m++;
						}
					}
					if (t == c)
						continue;
					for (int j = n - 1 ; j >= i ; j--)		//不够再从小往大拿 
					{
						if (!coin[j].m)
							continue;
						if (t + coin[j].m * coin[j].v >= c)		//够拿就拿
						{
							ans++;
							coin[j].m -= (c - t + coin[j].v - 1) / coin[j].v;
							t = c;		//管它后来是多少钱,就按c算 
							break;
						}
						else		//不够就先拿完 
						{
							t += coin[j].m * coin[j].v;
							coin[j].m = 0;
						}
					}
					if (t < c)		//如果还不够拿,则无法再发工资
					{
						flag = false; 
						break;
					}
				}
			}
			if (!flag)
				break;
		}
		printf ("%I64d\n",ans);
	}
	return 0;
} 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档