倒水问题

http://codevs.cn/problem/1226/
题目描述 Description
有两个无刻度标志的水壶,分别可装 x 升和 y 升 ( x,y 为整数且均不大于 100 )的水。设另有一水 缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶间,水也可以相互倾倒。已知 x 升壶为空 壶, y 升壶为空壶。问如何通过倒水或灌水操作, 用最少步数能在x或y升的壶中量出 z ( z ≤ 100 )升的水 来。

输入描述 Input Description
一行,三个数据,分别表示 x,y 和 z;

输出描述 Output Description
一行,输出最小步数 ,如果无法达到目标,则输出”impossible”

样例输入 Sample Input
3 22 1

样例输出 Sample Output
14

超经典的深搜题。又想起当年入门时的艰辛了。

#include <iostream>
#include <stdio.h>
#define MAXN 200
#define INF 10000000
using namespace std;
int f[MAXN][MAXN]={0},a,b,z; //f[x][y]=达到A桶内水量为x,B桶内水量为y的状态所需步骤数
void dfs(int x,int y,int step) //x=A桶内水量,y=B桶内水量,step=当前步骤数
{
    if(f[x][y]!=0&&step+1>=f[x][y]) return; //当前状态已经有解且现在的解一定比过去的解更差时,退出
    f[x][y]=step+1; //更新当前状态所需最少步骤数
    dfs(x,0,step+1); //1、清空B桶
    dfs(0,y,step+1); //2、清空A桶
    dfs(x,b,step+1); //3、装满B桶
    dfs(a,y,step+1); //4、装满A桶
    //5、将B桶倒入A桶
    if(x+y<=a)
        dfs(x+y,0,step+1);//(i)B桶倒空后A桶不会溢出
    else
        dfs(a,x+y-a,step+1); //(ii)B桶倒空后A桶会溢出,故B桶中有残留
    //6、将A桶倒入B桶
    if(x+y<=b)
        dfs(0,x+y,step+1);//(i)A桶倒空后B桶不会溢出
    else
        dfs(x+y-b,b,step+1); //(ii)A桶倒空后B桶会溢出,故A桶中有残留
}
int main()
{

 cin>>a>>b>>z;
 int minn=INF,i;
 dfs(0,0,0);
 for(i=0;i<=a;i++)
        if(f[i][z]!=0)
            if(f[i][z]<minn)
                minn=f[i][z]; //遍历所有B桶中达到水量z的情况,获得最优解
    for(i=0;i<=b;i++)
        if(f[z][i]!=0)
            if(f[z][i]<minn)
                minn=f[z][i];
 if(minn==INF)cout<<"impossible"<<endl;
 else cout<<minn-1<<endl;
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值