标签: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