博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 10626 Buying Coke
阅读量:7174 次
发布时间:2019-06-29

本文共 1498 字,大约阅读时间需要 4 分钟。

UVA_10626

    实际上我们注意到硬币的总状态不是很多,约是500*100*50(当然这么说并不准确,后面会再算),所以我们可以把硬币的组合形式看成一个状态。

    剩下的问题就是如何转移状态,我们细算一下,发现花钱的策略不过这么几种,如果再分细一些,可以先分成有找零的和没找零的:①8个1分的;②3个1分的和1个5分的;③2个5分的找回2个1分的;④一个10分的找回2个1分的;⑤3个1分的和1个10分的找回1个5分的。其余的可能也有,但一定不会比上面五种决策更优。

    显然递推是不好搞的,所以就不妨记忆化搜索吧。但注意到,我们按上面的策略花钱时,有些硬币是会增加的,所以我们要把上限算好。首先,③和④会增加1分的数量,最多增加的数量不会超过200个,其次⑤会增加5分的数量,但不会超过50个,于是开个710*160*60的数组即可。

#include
#include
#define INF 1000000000 int f[710][160][60], C, N, X, Y, Z; int dp(int n1, int n5, int n10) {
int i, j, k, min = INF; if(f[n1][n5][n10] != -1) return f[n1][n5][n10]; if(n1 + n5 * 5 + n10 * 10 == N) return f[n1][n5][n10] = 0; if(n1 >= 3 && n5 >= 1) {
k = dp(n1 - 3, n5 - 1, n10); if(k + 4 < min) min = k + 4; } if(n5 >= 2) {
k = dp(n1 + 2, n5 - 2, n10); if(k + 2 < min) min = k + 2; } if(n1 >= 3 && n10 >= 1) {
k = dp(n1 - 3, n5 + 1, n10 - 1); if(k + 4 < min) min = k + 4; } if(n10 >= 1) {
k = dp(n1 + 2, n5, n10 - 1); if(k + 1 < min) min = k + 1; } if(n1 >= 8) {
k = dp(n1 - 8, n5, n10); if(k + 8 < min) min = k + 8; } return f[n1][n5][n10] = min; } void solve() {
int res; scanf("%d%d%d%d", &C, &X, &Y, &Z); N = X + 5 * Y + 10 * Z - C * 8; memset(f, -1, sizeof(f)); res = dp(X, Y, Z); printf("%d\n", res); } int main() {
int t; scanf("%d", &t); while(t --) {
solve(); } return 0; }

转载地址:http://smbzm.baihongyu.com/

你可能感兴趣的文章
requests从api中获取数据并存放到mysql中
查看>>
23种设计模式之组合模式(Composite)
查看>>
button按钮点击不刷新(前端交流学习:452892873)
查看>>
安卓 使用Gradle生成正式签名apk文件
查看>>
@Html.Raw()
查看>>
ES6 Proxy
查看>>
图的基本算法(BFS和DFS)
查看>>
Linux时区详解
查看>>
61.node.js开发错误——Error: Connection strategy not found
查看>>
算法逆向第一篇——简单算法逆向
查看>>
机房收费系统数据库概念结构设计
查看>>
NanoJIT
查看>>
一个最简单GAL游戏资源文件黑盒分析(二)
查看>>
SQL Server 2005允许远程连接的配置说明
查看>>
HQL 语句
查看>>
用实现ajax读博客rss示例代码
查看>>
MVC验证12-使用DataAnnotationsExtensions对整型、邮件、最小值、文件类型、Url地址等验证...
查看>>
hdu1962Corporative Network带权回路
查看>>
全神贯注!聚精会神!一心一意!
查看>>
IBATIS事务处理 - - 博客频道 - CSDN.NET
查看>>