Codeforces Round 931 (Div. 2) B. Yet Another Coin Problem

作者有话说

写这篇题解不是因为它有多难,只是因为本人太菜了,以此来警示自己,虽然还没找到合适的提高算法能力的手段,但是至少不能消极态度,熬夜写这篇题解,希望未来的我看到后能引以为戒

解题思路

这个题第一眼就是动态规划,高高兴兴的没发现数据范围到1e9

写完以后盯着没过的样例愣住了,愣了一个半小时(菜的我无地自容)

考完以后看着这5个面值有了想法

正式开始

首先这个数据肯定是想让我们一下算出来的

通过观察,我们发现,1、3、6、10、15,这5个看起来没什么关系的数字实际上他们的最小公倍数是30,也就是说我们完全可以把金额拆成好多个30来解决,因为30的最佳方案一定是两枚15的硬币

想到这里,呆呆的我又开始写了贪心,结果依然是没有过

问题就在这了,虽然可以拆成好多30,但是十有八九这个数字不能被30整除,所以一定会空出来一个不足30的数字

30的部分可以用15面值的直接解决,那不足30的呢
还记得我开头说的动态规划吗,没错,如果数据范围到30就完全没问题了

所以我们只需要提前准备好一个30以内所有情况的答案,然后根据上述所言直接出答案即可。

看代码大家就很容易明白了

总代码

#include<bits/stdc++.h>
using namespace std;
const int num[] = {1,3,6,10,15};
int Mi[31];
int t,o;
void init()
{
	memset(Mi,0x3f,sizeof Mi);
	Mi[0] = 0;
	for(int i=0;i<5;i++){
		for(int j=num[i];j<31;j++){
			Mi[j] = min(Mi[j],Mi[j-num[i]] + 1);
		}
	}
}
int main()
{
	init();
	cin >> t;
	while (t--){
		cin >> o;
		int num = (o/15 == 0 ? 0 : o/15-1);
		o -= num * 15;
		cout << num + Mi[o] << endl;
	}
	return 0;
}

结语

临时起意,如果题解有帮助那是我的荣幸,我希望我能领悟到算法的学习,能让我觉得自己没那么菜了

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值