• 习题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;
    }
    

      

  • 相关阅读:
    java的概述 常量 变量
    css 基础2
    css 盒子模型1
    css 基础1
    HTML 基础 3
    HTML基础2
    servletContext百科
    hibernate 一对多双向关联 详解
    hibernate generator class="" id详解
    Hibernate缓存原理与策略
  • 原文地址:https://www.cnblogs.com/Przz/p/5409677.html
Copyright © 2020-2023  润新知