UVA1631 Locker
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的主要内容,如果未能解决你的问题,请参考以下文章
HDU 4433 locker(DP)( UVA 1631 - Locker)