UVA1631 Locker

题解:

记忆化搜索

dp[i][x][y][z]表示在第i个位置时,第i个位置为x(第i个位置匹配),第i+1个位置为y,第i+2个位置为z时的最小数目

代码:

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define LL long long
#define CLR(x) memset(x,0,sizeof x)
#define MC(x,y) memcpy(x,y,sizeof(x))
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=1050;
const int mod=1e9+7;
const int INF=1e9;

char s1[maxn],s2[maxn];
int  a[maxn],b[maxn];
int dp[1050][10][10][10];
int n;

int DP(int d,int x,int y,int z)
{
    if(d==n) return 0;
    int &m=dp[d][x][y][z];
    if(m>=0) return m;
    int up=(b[d]+10-x)%10,down=(x+10-b[d])%10;
    int ans=INF;
    for(int i=0;i<=up;i++)//用2转移的范围
    for(int j=0;j<=i;j++) ans=min(ans,DP(d+1,(y+i)%10,(z+j)%10,a[d+3])+up);//用3转移的范围
    for(int i=0;i<=down;i++)
    for(int j=0;j<=i;j++) ans=min(ans,DP(d+1,(y+10-i)%10,(z+10-j)%10,a[d+3])+down);
    return m=ans;
}
//可以优化10个单位的空间即dp[1050][10][10]

int main()
{
    while(~scanf("%s %s",s1,s2))
    {
        n=strlen(s1);
        for(int i=0;i<n;i++)
        {
            a[i]=s1[i]-‘0‘;
            b[i]=s2[i]-‘0‘;
        }
        memset(dp,-1,sizeof(dp));
        printf("%d\n",DP(0,a[0],a[1],a[2]));
    }
    return 0;
}
时间: 2025-01-31 07:03:59

UVA1631 Locker的相关文章

UVA1631 密码锁 Locker

题意翻译 有一个n(n≤1000)位密码锁,每位都是0-9,可以循环旋转.每次让1-3个相邻数字同时往上或者往下转一格,567890->567901(最后3位向上).输入初始状态和终止状态(长度不超过1000),问最少要转几次. 题目描述 PDF 输入输出格式 输入格式: 输出格式: 输入输出样例 暂无测试点 dp[i][j][k][l] 表示到第i个,第i个数为j,i+1的数为k,i+2的数为l #include<bits/stdc++.h> #define inf 0x3f3f3f3

locker doors

1 #include <math.h> 2 #include <stdio.h> 3 int f(int n) 4 { 5 int i, t, r = 0, q = (int)sqrt(n);//开方了 6 for (i=1; i<=q; ++i) 7 { 8 if (n%i == 0) 9 { 10 t = n/i; 11 if (t != i) 12 { 13 r += 2; 14 } 15 else 16 { 17 ++r; 18 } 19 } 20 } 21 retu

HDU 4433 locker(三维dp)

这题不太好想啊....我以为是记忆化搜索但是感觉最后的状态不好转移啊.别人都是用三维dp写的,感觉很巧啊. binshen写的:http://www.cnblogs.com/kuangbin/archive/2012/10/27/2742672.html 这题的意思就相当于是一个数字密码锁. 每次可以正向或者反向旋转连续的1-3个数字.求从现在状态转到目标状态需要的最少步数. 题目给了两个长度一样的由0-9组成的字符串.就相当于每次操作可以选择连续的1-3个数字加1或者减1.这不过这个加和减是循

UVA 12712 Pattern Locker(简单排列组合数学题)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4450 不懂取模运算的请猛戳:http://baike.baidu.com/link?url=A86lTLorv-Mim9g6v8EW3mY98qLz10cot1UCt6TZNPDJyslVYS5Ya1K

Postfix邮箱(八):安装反垃圾邮件系统Spam Locker

说明:Spam Locker是一款开放源代码,并以GPL授权发布,起源于APF技术,以SMTP行为识别为核心的反垃圾邮件系统.使用Perl语言撰写: Spam Locker使用了多种目前反垃圾邮件领域的领先技术,比如本地黑白名单.灰名单技术,多RBL查询技术等等: 这些众多厂商引以为豪的反垃圾邮件技术,现在都可以通过Spam Locker免费使用: Spam Locker是smtp阶段(邮件没收下来时),spamassassin是内容过滤阶段(邮件已经收下来了),所以2者可以混用. 参考: ht

Locker

题意: 有2个数字串,每次可以变化1-3位(每位+1或-1(0-9,9-0)可循环),求由1串变到2串的最小用的次数. 分析: dp[i][num]表示变到第i位时最后两位组成的数是num时最小次数(因为dp[i-1][num1],num1肯定是i位数的i-1,i-2位数,dp[i][num]=min(dp[i-1][num1]+cost[p][q])cost[p][q]表示(p,q后三位数字最小转化次数,可以预处理,要细心) #include <map> #include <set&g

UVa 12712 &amp;&amp; UVaLive 6653 Pattern Locker (排列组合)

题意:给定 一个n * n 的宫格,就是图案解锁,然后问你在区间 [l, r] 内的所有的个数进行组合,有多少种. 析:本来以为是数位DP,后来仔细一想是排列组合,因为怎么组合都行,不用考虑实际要考虑的比如 要连13,必须经过2,这个可以不用. 所以这题就是A(n,m).剩下的就简单了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <s

HDU 4433 locker(DP)( UVA 1631 - Locker)

题目链接:点击打开链接 题意:有一个n位密码锁,每一位都是0~9,可以循环旋转,每次可以让1~3个相邻数字同时往上或者往下旋转一格. 输入初始状态和终止状态,问最少需要转几次. 思路: 很显然是个DP题目, 由于每次可以让相邻的1~3个数字同时旋转, 所以状态的表示上就要考虑相邻3个位置. 那么可以用d[i][a][b][c]表示当前到了第i位,第i位上当前是a,i+1位是b,i+2位是c. 那么显然必须让i位上变成目标数字了, 因为接下来就转移到i+1位了,说明前i位已经全部转到目标态了.  

UVa 1631 Locker (DP)

题意:有一个 n 位密码锁,每位都是0-9,可以循环旋转.同时可以让1-3个相邻数字进行旋转一个,给定初始状态和目状态,问你最少要转多少次. 析:很明显的一个DP题.dp[i][j][k] 表示前 i 位已经转好,并且第 i+1 位是 j ,第 i+2 位是 k,那么我们先把第 i 位转到指定位置,然后计算转多少次, 然后再考虑 i+1位和 i+2位,要旋转小于等于第 i 位的次数,这就转移完了.比较简单的一个DP,只是没有遇见过. 代码如下: #pragma comment(linker, "