首页 > 代码库 > UVA1631 Locker

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;
}

 

UVA1631 Locker