• HDU 1584 蜘蛛牌 (dfs)


    题面

    Problem Description
    蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。

    Input
    第一个输入数据是T,表示数据的组数。
    每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。

    Output
    对应每组数据输出最小移动距离。

    Sample Input
    1
    1 2 3 4 5 6 7 8 9 10

    Sample Output
    9

    思路

    搜索题,我们这里选择dfs不要问为什么,直觉(据说可以区间dp?)。这题题面看上去简单,代码实现也不难,但是仔细想还是有很多值得推敲的点的,难怪是dfs的经典题目,我们先从整体上来看,我们移动某张牌,只能去寻找下一张比他大一的牌,但是有这样的情况:这张牌已经不在原来位置上了,他在之前已被移动了,所以我们应该继续找下去,当我们行走的部数到9的时候,就应该停止搜索,因为最多我们只需要走9步。然后这题的话我们需要加应该小的剪枝,就是当不熟大于当前最小部署的时候停止搜索。哦,对了,不要忘记回溯哦,亲。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define eps 1e-4
    const int maxn=10005;
    int ans;
    int vis[maxn], sit[maxn];
    void dfs (int x,int step) {
        if (step>=ans) return ;
        if (x==9) {
           ans=step;
           return ;
        } 
        for (int i=1;i<11;i++) {
           if (!vis[i]) {
              vis[i]=1;
              for (int j=i+1;j<11;j++) {
                 if (!vis[j]) {
                    dfs (x+1,step+abs(sit[i]-sit[j]));
                    break;
                 }
              }
              vis[i]=0;
           }
        }
    }
    int main () {
       int t;
       int x;
       cin>>t;
       while (t--) {
          memset(vis,0,sizeof (vis));
          for (int i=0;i<10;i++) {
             cin>>x;
             sit[x]=i;
          }
          ans=0x3f3f3f3f;
          dfs (0,0);
          cout<<ans<<endl;
       }
        return 0;
    }
    
  • 相关阅读:
    2017《Java技术》预备作业 计科1501 杨欣蕊
    Java技术预备作业02杨欣蕊
    系统无法从光盘启动
    动态数组ArrayList的使用
    dbgrid数据显示和数据源不同
    异步任务判断服务器是否开启
    Java字符串格式化
    思科2960 监听端口设置
    64位win7安装jdk和eclipse
    Delphi临界区的使用
  • 原文地址:https://www.cnblogs.com/hhlya/p/13123499.html
Copyright © 2020-2023  润新知