[USACO-Training 1.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.

PROGRAM NAME
milk3

INPUT FORMAT
A single line with the three integers A, B , and C.

SAMPLE INPUT (file milk3.in)
8 9 10

OUTPUT FORMAT
A single line with a sorted list of all the possible amounts of milk that can be in bucket C when bucket A is empty.

SAMPLE OUTPUT (file milk3.out)
1 2 8 9 10

SAMPLE INPUT (file milk3.in)
2 5 10

SAMPLE OUTPUT (file milk3.out)
5 6 7 8 9 10

题目大意
就是说给你 A B C 三个桶,一开始只有C桶有牛奶,只能将一个桶倒空或者倒满,并且不能溢出,问当 A 桶没有牛奶时C桶牛奶数量的情况,升序输出。

思路
这道题USACO上卡输出……
不断枚举加记忆化搜索就可以了。

代码

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

const int maxn=20;

int f[maxn+1][maxn+1][maxn+1],tot;
int amax,bmax,cmax,ans[maxn+1],x[maxn+1];

int search(int a,int b,int c)
{
  if(f[a][b][c])
    {
      return 0;
    }
  f[a][b][c]=1;
  if(!a)
    {
      ans[c]=1;
    }
  search(a-std::min(a,bmax-b),b+std::min(a,bmax-b),c);
  search(a-std::min(a,cmax-c),b,c+std::min(a,cmax-c));
  search(a+std::min(b,amax-a),b-std::min(b,amax-a),c);
  search(a,b-std::min(b,cmax-c),c+std::min(b,cmax-c));
  search(a+std::min(c,amax-a),b,c-std::min(c,amax-a));
  search(a,b+std::min(c,bmax-b),c-std::min(c,bmax-b));
  return 0;
}

int main()
{
  freopen("milk3.in","r",stdin);
  freopen("milk3.out","w",stdout);
  scanf("%d%d%d",&amax,&bmax,&cmax);
  search(0,0,cmax);
  for(register int i=0; i<=cmax; ++i)
    {
      if(ans[i])
        {
          ++tot;
          x[tot]=i;
        }
    }
  for(register int i=1; i<tot; ++i)
    {
      printf("%d ",x[i]);
    }
  printf("%d\n",x[tot]);
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值