zoukankan      html  css  js  c++  java
  • UVA 10603 Fill

    UVA_10603

    这个题目和普通的倒水问题不同的是,它不是去求最少的倒水次数,而是求最少的倒水量。普通倒水问题的解法可以参考刘汝佳白书P131

    因而我们的判重的时候不能笼统地把所有重复的状态都抛弃,因为有些状态尽管是相同的,但倒水量却有可能不同。

    于是我们在判重之前,也应分析一下这个状态会不会对我们记录的达到某一水量时所需的倒水总量进行更新,如果进行了更新,那么即使状态与之前相同,我们也应把这个状态当作一个新的状态来处理。

    那么既然如果更新了记录即便是重复的状态也要当作新状态来处理,我们还有必要进行判重吗?实际上也存在着没有更新记录但确实是一个新状态的情况。

        此外,在判重的时候运用了哈希的思想,由于这个题目节点数比较少,所以写一个完美哈希还是比较容易的。

    #include<stdio.h>
    #include
    <string.h>
    int hash[8200000],water[210];
    int q[3][8200000],st[8200000],a[5];
    int insert(newa,newb,newc)
    {
    int h=0;
    h
    =201*201*newa+201*newb+newc;
    if(!hash[h])
    {
    hash[h]
    =1;
    return 1;
    }
    else
    return 0;
    }
    int main()
    {
    int i,j,k,t,front,rear,pour,ok;
    int A[5],D,newa[5];
    scanf(
    "%d",&t);
    while(t--)
    {
    scanf(
    "%d%d%d%d",&A[0],&A[1],&A[2],&D);
    memset(hash,
    0,sizeof(hash));
    memset(water,
    -1,sizeof(water));
    a[
    0]=0;
    a[
    1]=0;
    a[
    2]=A[2];

    front
    =rear=0;
    st[rear]
    =0;
    for(i=0;i<3;i++)
    {
    q[i][rear]
    =a[i];
    water[a[i]]
    =st[rear];
    }
    rear
    ++;
    while(front<rear)
    {
    for(i=0;i<3;i++)
    a[i]
    =q[i][front];
    front
    ++;
    for(i=0;i<3;i++)
    for(j=0;j<3;j++)
    if(i!=j)
    if(a[i]!=0&&a[j]!=A[j])
    {
    if(a[i]>A[j]-a[j])
    {
    pour
    =A[j]-a[j];
    newa[i]
    =a[i]-pour;
    newa[j]
    =A[j];
    }
    else
    {
    pour
    =a[i];
    newa[i]
    =0;
    newa[j]
    =a[j]+pour;
    }
    for(k=0;k==i||k==j;k++);
    newa[k]
    =a[k];
    st[rear]
    =st[front-1]+pour;
    ok
    =0;
    for(k=0;k<3;k++)
    {
    q[k][rear]
    =newa[k];
    if(water[newa[k]]<0||st[rear]<water[newa[k]])
    {
    ok
    =1;
    water[newa[k]]
    =st[rear];
    }
    }
    if(insert(newa[0],newa[1],newa[2])||ok)
    rear
    ++;
    }
    }
    if(water[D]!=-1)
    printf(
    "%d %d\n",water[D],D);
    else
    {
    for(i=D;;i--)
    if(water[i]!=-1)
    break;
    printf(
    "%d %d\n",water[i],i);
    }
    }
    return 0;
    }

      

  • 相关阅读:
    用sed删除空行
    烂泥:php5.6源码安装及php-fpm配置
    linux系统vsftpd登陆慢卡怎么办
    Linux Vsftpd 连接超时解决方法
    linux中shell截取字符串方法总结
    运算符
    数据类型
    is null 和=null的区别
    DML
    DDL
  • 原文地址:https://www.cnblogs.com/staginner/p/2173511.html
Copyright © 2011-2022 走看看