給定兩個數字字串,每次操作只能將相鄰的1-3位數字向上或向下旋轉1位,問從第乙個字串到第二個字串最少需要多少步。
很經典的記憶化搜尋問題,用dp[i][a][b][c]表示前i-1位已經旋轉好了,第i位為a,第i+1位為吧,第i+2位為c時,將這三位旋轉好的最小移動次數。那麼首先,第i位旋轉好可以向下或向上旋轉,這是起始位置;當第i位旋轉好的步驟為step步時,第i+1位可能旋轉的步驟是0~step,,第i+2位旋轉的步驟0~第i+1旋轉的步驟,那麼就列舉所有情況,取最小值即可。
**:
#include #include #include #include #include #include #include using namespace std;
/* dp[i][a][b][c]表示前i-1位已經匹配,第i,i+1,i+2分別為a,b,c的最小移動次數
遍歷當第i位旋轉好時,i+1,i+2位的旋轉情況
記憶化搜尋
*/const int inf=0x3f3f3f3f;
const int maxn=1010;
int dp[maxn][12][12][12];
char str1[maxn],str2[maxn];
int s[maxn],g[maxn];
int n;
int idx(char c)
int dp(int index,int a,int b,int c)
}//向下旋轉
if(a<=g[index])step=a+10-g[index];
else step=a-g[index];
for(int i=0;i<=step;i++)
}return ans;
}int main()
s[n]=s[n+1]=0;
g[n]=g[n+1]=0;
printf("%d\n",dp(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 Locker 記憶化搜尋
題意 給定兩個密碼串,每次可以讓1 3個相鄰的密碼向上或者向下滾動,每個密碼是0 9 問最少需要多少次滾動可以讓原串成為目標串?思路 假設當前要讓第i位密碼還原,我們可以同時轉動 i i 1 i 2 i i 1 i 不同的轉動方式會影響後序的轉動,那麼可以列舉 i i 1 i 2 三個密碼的轉動情況...
搜尋 問題 D 神奇密碼鎖
這道題個人認為隱含著狀態轉換,所以想到的還是bfs,將其中一位數加一或減一或交換臨近兩位,進入下一狀態,使用乙個大小為10000的bool陣列判重,由於bfs的特性,得到的一定是最小步數 普通bfs 如下 include include include include using namespace...