動態規劃:(二維)地下城遊戲,最大公共子串

地下城遊戲(leetcode)

一些惡魔抓住了公主(P)並將她關在了地下城的右下角。地下城是由 M x N 個房間組成的二維網格。我們英勇的騎士(K)最初被安置在左上角的房間裏,他必須穿過地下城並通過對抗惡魔來拯救公主。

騎士的初始健康點數爲一個正整數。如果他的健康點數在某一時刻降至 0 或以下,他會立即死亡。

有些房間由惡魔守衛,因此騎士在進入這些房間時會失去健康點數(若房間裏的值爲負整數,則表示騎士將損失健康點數);其他房間要麼是空的(房間裏的值爲 0),要麼包含增加騎士健康點數的魔法球(若房間裏的值爲正整數,則表示騎士將增加健康點數)。

爲了儘快到達公主,騎士決定每次只向右或向下移動一步。

#include<vector>
#include <iostream>
#include<algorithm>
using namespace std;
using std::max;
using std::min;
class Solution {
public:
	int calculateMinimumHP(vector<vector<int>>& dungeon) {
		const int M = dungeon.size(), N = dungeon[0].size();
		vector<vector<int>> dp(M + 1, vector<int>(N + 1, INT_MAX));
		dp[M][N - 1] = dp[M - 1][N] = 1;
		for (int i = M - 1; i >= 0; i--) {
			for (int j = N - 1; j >= 0; j--) {
				dp[i][j] = max(1, min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]);
			}
		}
		return dp[0][0];
	}
};

公共子串

查找兩個字符串a, b中的最長公共子串。若有多個,輸出在較短串中最先出現的那個。

//查找兩個字符串a, b中的最長公共子串。若有多個,輸出在較短串中最先出現的那個。
void findMaxCommonStr(string s1, string s2)
{
	if (s1.length() > s2.length())
		swap(s1, s2);//s1用於保存較短的子串
	int len1 = s1.length(), len2 = s2.length();
	int maxLen = 0, start = 0;
	vector<vector<int> >dp(len1 + 1, vector<int>(len2 + 1, 0));
	for (int i = 1; i <= len1; ++i)
		for (int j = 1; j <= len2; ++j)
		{
			if (s1[i - 1] == s2[j - 1])
			{
				dp[i][j] = dp[i - 1][j - 1] + 1;
				if (dp[i][j] > maxLen)
				{
					maxLen = dp[i][j];
					start = i - maxLen;//記錄最長公共子串的起始位置
				}
			}
		}
	cout << s1.substr(start, maxLen) << endl;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章