[USACO1.4]母亲的牛奶 Mother's Milk 搜索

题目

Farmer John has three milking buckets of capacity A, B, and C liters. Each of the numbers A, B, and C is an integer from 1 through 20, inclusive. Initially, buckets A and B are empty while bucket C is full of milk. Sometimes, FJ pours milk from one bucket to another until the second bucket is filled or the first bucket is empty. Once begun, a pour must be completed, of course. Being thrifty, no milk may be tossed out.

Write a program to help FJ determine what amounts of milk he can leave in bucket C when he begins with three buckets as above, pours milk among the buckets for a while, and then notes that bucket A is empty…

农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的。有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了。当然每一次灌注都是完全的。由于节约,牛奶不会有丢失。

写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。

题解

记忆化搜索,搜索所有可能性
每次从非空的桶尝试往另外两个桶倒牛奶

代码

/*
ID: yjy_aii1
TASK: milk3
LANG: C++
*/
#include <cstdio>
#include <algorithm>

using namespace std;

int a,b,c;
int bz[24][24][24];
bool cz[24];

void dfs(int x,int y,int z){
	if (bz[x][y][z]==1) return;
	bz[x][y][z]=1;
	if (x==0) cz[z]=1;
	if (x>0){
		if (y<b) dfs(x-min(x,b-y),y+min(x,b-y),z);
		if (z<c) dfs(x-min(x,c-z),y,z+min(x,c-z));
	}
	if (y>0){
		if (x<a) dfs(x+min(y,a-x),y-min(y,a-x),z);
		if (z<c) dfs(x,y-min(y,c-z),z+min(y,c-z));
	}
	if (z>0){
		if (x<a) dfs(x+min(z,a-x),y,z-min(z,a-x));
		if (y<b) dfs(x,y+min(z,b-y),z-min(z,b-y));
	}
}

int main(){
	freopen("milk3.in","r",stdin);
	freopen("milk3.out","w",stdout);
	scanf("%d%d%d",&a,&b,&c);
	dfs(0,0,c);
	int i=0;
	while (!cz[i]&&i<=c) i++;
	printf("%d",i);
	i++;
	for (i;i<=c;i++)
		if (cz[i]) printf(" %d",i);
	printf("\n");
}

清秋凝冰河

义无反顾的洛河啊
你是渭水的孩子
渭水是黄河的孩子
你奔涌,你狂躁,你决绝
像黄河渭水一样的自高原流下
你凌厉的水花打湿了姑娘的面颊

清秋,清秋,这清冷的深秋
终于是你安宁的时候
洛河凝结成冰,还清秋一季清静
刹那间,冰封山巅,偷得转瞬清闲,已是天上人间

“铁马冰河入梦来”

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值