标签:des style blog http io ar color os sp
这题不太好想啊。。。。我以为是记忆化搜索但是感觉最后的状态不好转移啊。别人都是用三维dp写的,感觉很巧啊。
binshen写的:http://www.cnblogs.com/kuangbin/archive/2012/10/27/2742672.html
这题的意思就相当于是一个数字密码锁。
每次可以正向或者反向旋转连续的1-3个数字。求从现在状态转到目标状态需要的最少步数。
题目给了两个长度一样的由0-9组成的字符串。就相当于每次操作可以选择连续的1-3个数字加1或者减1.这不过这个加和减是循环的。0减1到9,9加1到0.
一看就是DP。
这不过DP方程不好想,也不好表示状态。
dp[i][x][y]表示处理到第i个,后面两个数字是x,y,把前i位转正确需要的最少步数。
计算dp[i][x][y]时,前i-2位是题目给的现在状态的值,第i-1位是x,第i位是y,就是把前i位转正确。
要把dp[i]的状态转移到dp[i-1]去。
把第i位从x转到目标态b[i]去,就可以把状态转移了。
和第i位相关的转动有三种:一是单转第i位,二是转第i位和第i-1位,三是转第i位、第i-1位和第i-2位。
根据三种可以确定 dp[i-1][xx][yy]中的xx,yy;
转动分为正转和反转。
如果第i位是正转,转正确需要d1步。
那么第i-1和第i-2位正转的不是是小于等于d1的。而且i-2的步数小于等于i-1。
如果第i位是正转,转正确需要d2步。
那么第i-1和第i-2位正转的不是是小于等于d2的。而且i-2的步数小于等于i-1。
这样DP的时候i从1到n转移过去。
处理dp[i]的时候,dp[1~(n-1)][0~9][0~9]都是已知的。就很容易确定dp[i][0~9][0~9]的最小值了。
111111 222222 896521 183995
2 12
#include <algorithm> #include <iostream> #include <stdlib.h> #include <string.h> #include <iomanip> #include <stdio.h> #include <string> #include <queue> #include <cmath> #include <time.h> #include <stack> #include <map> #include <set> #define eps 1e-8 ///#define LL long long #define LL __int64 #define INF 0x3f3f3f #define PI 3.1415926535898 #define mod 1000000007 using namespace std; const int maxn = 1010; int dp[maxn][10][10]; char str1[maxn], str2[maxn]; int num1[maxn]; int num2[maxn]; int main() { while(~scanf("%s %s",str1, str2)) { int n = strlen(str1); for(int i = 0; i < n; i++) { num1[i+1] = str1[i]-'0'; num2[i+1] = str2[i]-'0'; } for(int i = 0; i <= n; i++) for(int j = 0; j < 10; j++) for(int k = 0; k < 10; k++) dp[i][j][k] = INF; dp[0][0][0] = 0; for(int i = 1; i <= n; i++) { for(int x = 0; x < 10; x++) { if(i <= 1 && x > 0) break; for(int y = 0; y < 10; y++) { int dx = (num2[i]-y+10)%10; int dy = (y-num2[i]+10)%10; int xx, yy; if(i == 1) { xx = yy = 0; dp[i][x][y] = min(dp[i][x][y], dp[i-1][xx][yy]+min(dx, dy)); continue; } if(i == 2) { xx = 0; for(int j = x; j <= x+dx; j++) { yy = j%10; dp[i][x][y] = min(dp[i][x][y], dp[i-1][xx][yy]+dx); } for(int j = x; j >= x-dy; j--) { yy = (j+10)%10; dp[i][x][y] = min(dp[i][x][y], dp[i-1][xx][yy]+dy); } continue; } for(int j = 0; j <= dx; j++) { for(int k = j; k <= dx; k++) { xx = (num1[i-2]+j)%10; yy = (x+k)%10; dp[i][x][y] = min(dp[i][x][y], dp[i-1][xx][yy]+dx); } } for(int j = 0; j <= dy; j++) { for(int k = j; k <= dy; k++) { xx = (num1[i-2]-j+10)%10; yy = (x-k+10)%10; dp[i][x][y] = min(dp[i][x][y], dp[i-1][xx][yy]+dy); } } } } } int x = 0; int y = 0; if(n >= 2) x = num1[n-1]; if(n >= 1) y = num1[n]; cout<<dp[n][x][y]<<endl; } return 0; }
标签:des style blog http io ar color os sp
原文地址:http://blog.csdn.net/xu12110501127/article/details/41520157