1226 倒水问题

1226 倒水问题

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
 
 
题目描述 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

数据范围及提示 Data Size & Hint
 

分类标签 Tags 点此展开 

 
#include<cstdio>
#include<iostream>
#define MAXN 200
#define INF 10000000
using namespace std;
int f[MAXN][MAXN],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()
{
    int ans=INF;
    scanf("%d%d%d",&a,&b,&z);
    dfs(0,0,0);
    for(int i=1;i<=a;i++)
        if(f[i][z])
            ans=min(ans,f[i][z]); //遍历所有B桶中达到水量z的情况,获得最优解
    for(int i=1;i<=b;i++)
        if(f[z][i])
            ans=min(ans,f[z][i]);//遍历所有B桶中达到水量z的情况,获得最优解
    if(ans==INF) printf("impossible
");
    else printf("%d
",ans-1);
    return 0;
}
原文地址:https://www.cnblogs.com/shenben/p/5573345.html