返回顶部
大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。人生如梦,一尊还酹江月。

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 0x3f3f3f3f
using namespace std;

const int maxn = 1e3+10;

int kase=0,vis[maxn][10][10][10],f[maxn][10][10][10],n;

int a[maxn],b[maxn];

char aa[maxn],bb[maxn];

int dp(int cur,int x,int y,int z) {
    if(cur>=n) return 0;
    int& ans = f[cur][x][y][z];
    if(vis[cur][x][y][z]==kase) return ans;
    vis[cur][x][y][z]=kase;
    ans=inf;
    int t;
    if(x<=b[cur]) t=b[cur]-x;
    else t=b[cur]+10-x;
    for(int i=0;i<=t;i++)
        for(int j=0;j<=i;j++)
           ans=min(ans,dp(cur+1,(y+i)%10,(z+j)%10,a[cur+3])+t);
    if(x>=b[cur]) t=x-b[cur];
    else t=x+10-b[cur];
    for(int i=0;i<=t;i++)
        for(int j=0;j<=i;j++) 
            ans=min(ans,dp(cur+1,(y-i+10)%10,(z-j+10)%10,a[cur+3])+t);
    return ans;
}

int main() {
    //freopen("in.txt","r",stdin);
    while(scanf("%s%s",&aa,&bb)!=EOF) {
        ++kase;
        n=strlen(aa);
        for(int i=0;i<n;i++) a[i]=aa[i]-'0',b[i]=bb[i]-'0';
        a[n] = a[n + 1] = b[n] = b[n + 1] = 0;
        printf("%d\n",dp(0,a[0],a[1],a[2]));
    }
    return 0;
} 
View Code

 

posted @ 2019-05-18 18:06  plysc  阅读(199)  评论(0编辑  收藏  举报