zoukankan      html  css  js  c++  java
  • 习题9-8 uva1631

    题意:

    给你一串密码,每次我们可以转动1-3个数字,求转出最终答案的最小步数


    思路:
    感觉自己好坑,最开始想的是dp[cur][t1][t2][t3]也就是t1的位置以及连续的三个数的状态
    但是卡死循环了,于是乎改成dp[cur][t1][t2](当前的位置以及它后面的数的状态)
    每次求出当前位置转到正确答案时要的步数,然后枚举3种情况(也就是后面两个数是否一起转动)
    但是中途发现思路有问题,111  -->  322 这种它会给出答案三,然而应该是2
    (感觉最近课真的多,还要考试- -,都没时间做题)


    通过上面那个例子发现,当前位置并不是一次旋转到正确答案是最优解(感觉思考问题是太片面了)
    可能自己选转几格,再带动后面两个转动,322 -> 222 -> 111
    所以对于后两个的可能枚举0 --> t(t为转动到正确答案的步数)
    而且t2转动的步数≥a[cur+2]步数,因为第三个位置转动的前提便是t2转动
    所以得出个循环,然后记忆化搜索


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <functional>
    
    using namespace std;
    const int maxn = 1005;
    const int INF = 0x3f3f3f3f;
    char str1[maxn];
    char str2[maxn];
    int a[maxn];
    int b[maxn];
    int dp[maxn][10][10];
    int len;
    
    int up(int s,int t)             //上旋
    {
    
        if(s >= t)
            return s-t;
        else
            return (s-t+10)%10;
    }
    
    
    int down(int s,int t)          //下旋
    {
    
        if(t >= s)
            return t-s;
        else
            return (t-s+10)%10;
    }
    
    int DFS(int cur,int t1,int t2)
    {
        if(cur >= len)
            return 0;
        if(dp[cur][t1][t2] != -1)
            return dp[cur][t1][t2];
        int t = up(b[cur],t1);
        int ans = INF;
    
        for(int i = 0; i <=t; i++)            //枚举后个数的情况
            for(int j = i; j <= t; j++)
            {
                ans = min(ans,DFS(cur+1,(t2+j)%10,(a[cur+2]+i)%10) + t);
            }
    
        t = down(b[cur],t1);
        for(int i = 0; i <=t; i++)
            for(int j = i; j <= t; j++)
            {
                ans = min(ans,DFS(cur+1,(t2-j+10)%10,(a[cur+2]-i+10)%10) +t);
            }
        return dp[cur][t1][t2] = ans;
    }
    
    
    int main()
    {
        while(scanf("%s%s",str1,str2) != EOF)
        {
            len= strlen(str1);
            for(int i = 0; i < len; i++)
            {
                a[i] = str1[i] - '0';
                b[i] = str2[i] - '0';
            }
            a[len] = a[len+1] = b[len] = b[len+1] = 0; 
            memset(dp,-1,sizeof(dp));
            printf("%d
    ",DFS(0,a[0],a[1]));
        }
        return 0;
    }
    

      

  • 相关阅读:
    阿里云 ssl 证书 免费申请
    重启aliyun esc 需要重新启动redis
    SSL证书部署
    前端性能优化--合并请求
    npm 镜像修改
    google 浏览器插件安装
    离线安装.NET Framework 3.5
    A new session could not be created. (Original error: Could not find a connected Android device.)
    error: device unauthorized.
    pip 批量安装包
  • 原文地址:https://www.cnblogs.com/Przz/p/5409677.html
Copyright © 2011-2022 走看看