UVA - 10626 Buying Coke 多状态

题目大意:有个贩卖机卖可乐,每次只能买一次可乐,找零的时候他会按照最少的硬币数进行找零,要求买N瓶可乐,每瓶可乐价值为8,有三种硬币,价值分别为1,5,10,钱时够用的,问买N瓶可乐时往贩卖机丢入硬币的最小值

解题思路:这题的状态比较多,有四个,可乐的数量,三种硬币的数量,共有四个,舍去一个的可乐的数量的话,那还有三个,就用三维数组表示三种硬币的数量的状态,设dp[i][j][k]为价值1的硬币还有i个,5的有j个,10的有k个的丢入硬币的最低值。买可乐的话有5种买卖方式

1.1个十的找回2个一的

2.1个十的3个一的找回1个五的

3.2个五的找回2个一的

4.1个五的3个一的

5.8个一的

这五种是最优的选择

#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int dp[750][220][100];
bool vis[750][220][100];
int solve(int c,int n1,int n5,int n10) {
	int &res = dp[n1][n5][n10];
	bool &flag = vis[n1][n5][n10];
	if(flag)
		return res;
	else if(c == 0) {
		flag = 1;
		res = 0;
		return res;	
	}else {
		res = INF;
		if(n1 >= 8)
			res = min(res,solve(c-1,n1-8,n5,n10) + 8);
		if(n5 >= 1 && n1 >= 3)
			res = min(res,solve(c-1,n1-3,n5-1,n10) + 4);
		if(n10 >= 1 && n1 >= 3)
			res = min(res,solve(c-1,n1-3,n5+1,n10-1) + 4);
		if(n5 >= 2)
			res = min(res,solve(c-1,n1+2,n5-2,n10) + 2);
		if(n10 >= 1)
			res = min(res,solve(c-1,n1+2,n5,n10-1) + 1);

		
		flag = 1;
		return res;
	}
}
int main() {
	int test;
	scanf("%d",&test);
	while(test--) {
		int c,coin[3];
		scanf("%d%d%d%d",&c,&coin[0],&coin[1],&coin[2]);
		memset(vis,0,sizeof(vis));
		printf("%d\n",solve(c,coin[0],coin[1],coin[2]));


	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值