題意:給定兩個密碼串,每次可以讓1~3個相鄰的密碼向上或者向下滾動,每個密碼是0−
9 ,問最少需要多少次滾動可以讓原串成為目標串?
思路:假設當前要讓第i位密碼還原,我們可以同時轉動[i
,i+1
,i+2
],[i
,i+1
],[i
] ,不同的轉動方式會影響後序的轉動,那麼可以列舉(i
,i+1
,i+2
) 三個密碼的轉動情況來進行記憶化搜尋。 設d
p(i,
a,b,
c)表示當前已經還原了前i−
1 個密碼,且第
i 個密碼的值是a,第
i+1 個密碼的值是
b ,第i+
2個密碼的值是
c 的情況下需要的最小轉動次數。
ac**
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#pragma comment(linker, "/stack:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define pi pair
typedef
long
long ll;
const
int maxn = 1000 + 5;
int dp[maxn][10][10][10];
char st[maxn], ed[maxn];
int s[maxn], g[maxn], n;
int dfs(int cur, int a, int b, int c)
//向下旋轉
if(a <= g[cur]) step = a+10-g[cur];
else step = a-g[cur];
for(int i = 0; i <= step; ++i)
for(int j = 0; j <= i; ++j)
return ans;
}int main()
s[n] = s[n+1] = g[n] = g[n+1] = '0';
printf("%d\n", dfs(0, s[0], s[1], s[2]));
}return
0;}
如有不當之處歡迎指出! UVA 1631 記憶化搜尋
n位密碼鎖,每次可以向上或向下轉動1 3個密碼,問從初始狀態轉換到目標狀態最少需要轉動多少次。設dp cnt a b c 為當前位為cnt時,cnt位置上的值為a,cnt 1位置上的值為b,cnt 2位置上的值為c。此時將cnt位轉動到目標狀態,向上或向下轉動,根據向上或向下轉動後轉動的次數,選擇轉...
UVa 1631 密碼鎖 (記憶化搜尋)
給定兩個數字字串,每次操作只能將相鄰的1 3位數字向上或向下旋轉1位,問從第乙個字串到第二個字串最少需要多少步。很經典的記憶化搜尋問題,用dp i a b c 表示前i 1位已經旋轉好了,第i位為a,第i 1位為吧,第i 2位為c時,將這三位旋轉好的最小移動次數。那麼首先,第i位旋轉好可以向下或向上...
uva 116 (記憶化搜尋)
題意 如圖,從左到右走,每次可以往左上 up 左 fo 左下 dn 走,當走到第一行或最後一行時可以如圖穿越。求一條權值最小的路徑,並列印字典序最小的路徑。解析 狀態轉移方程 dp i j min dp i 1 m m j 1 up dp i j 1 fo dp i 1 m j 1 dn 字典序最小...