HIT研究生算法作业4

1、答:
定义: m a x S u m i 为 A [ 1 , . . . i ] 连 续 子 数 组 的 最 大 和 ; s u m i 为 当 前 连 续 子 数 组 的 和 maxSum_i为A[1,...i]连续子数组的最大和;sum_i为当前连续子数组的和 maxSumiA[1,...i];sumi,则有

递推方程:

s u m i = A [ i ] i f    i = 1    或    s u m i − 1 < 0 s u m i = s u m i − 1 + A [ i ] i f    s u m i − 1 > = 0 m a x S u m i = A [ i ] i f    i = 1 m a x S u m i = M a x ( m a x S u m i − 1 , s u m i ) sum_i = A[i] \qquad if \;i = 1\;或 \;sum_{i-1} < 0\\ sum_i = sum_{i-1} + A[i] \qquad if\; sum_{i-1} >=0\\ maxSum_i = A[i] \qquad if \; i = 1 \\ maxSum_i = Max(maxSum_{i-1}, sum_i) sumi=A[i]ifi=1sumi1<0sumi=sumi1+A[i]ifsumi1>=0maxSumi=A[i]ifi=1maxSumi=Max(maxSumi1,sumi)

算法伪代码:

  • 输入: 数 组 A [ 1 , 2.... n ] 数组A[1,2....n] A[1,2....n]
  • 输出:连续子数组的最大和
maxSubArray(A)
	maxSum <- A[1];
	sum <- A[1];
	for i <- 2 to n
		if sum < 0 Then
			sum <- A[i];
		else
			sum <- sum + A[i];
		maxSum = Max(maxSum, sum);
	return maxSum; 

时间复杂度分析:

  • 输入规模: n n n
  • 复杂度: O ( n ) O(n) O(n)

2、答:
定义: d p i 为 爬 到 第 i 阶 台 阶 的 方 法 数 dp_i 为爬到第i阶台阶的方法数 dpii,则有

递推方程:

d p 1 = 1 d p 2 = 2 d p i = d p i − 1 + d p i − 2 dp_1 = 1 \quad dp_2 = 2\\ dp_i = dp_{i-1} + dp_{i-2} dp1=1dp2=2dpi=dpi1+dpi2

算法伪代码:

  • 输入:台阶阶数 n n n
  • 输出:爬到 n n n阶的方法数
climbStairs(n)
	if n == 1 Then return 1;
	if n == 2 Then return 2;
	dp_i_1 <- 2;
	dp_i_2 <- 1;
	for i <- 3 to n
		dp_i <- dp_i_1 + dp_i_2;
		dp_i_2 = dp_i_1;
		dp_i_1 = dp_i;
	return dp_i;
		 

时间复杂度分析:

  • 输入规模: log ⁡ n \log{n} logn
  • 复杂度: O ( 2 log ⁡ n ) O(2^{\log{n}}) O(2logn)

3、答:
定义: d p [ i ] [ j ] 记 录 字 符 串 S 中 s i s i + 1 . . . s j 子 串 是 否 为 回 文 的 dp[i][j]记录字符串S中s_is_{i+1}...s_j子串是否为回文的 dp[i][j]Ssisi+1...sj,则有

递推方程:

d p [ i ] [ i ] = T r u e d p [ i ] [ i + 1 ] = T r u e i f    s i = s i + 1 d p [ i ] [ j ] = T r u e i f    d p [ i + 1 ] [ j − 1 ] = T r u e 且 s i = s j dp[i][i] = True \\ dp[i][i + 1] = True \quad if \; s_i = s_{i+1} \\ dp[i][j] = True \quad if \; dp[i + 1][j - 1] = True 且 s_i = s_j dp[i][i]=Truedp[i][i+1]=Trueifsi=si+1dp[i][j]=Trueifdp[i+1][j1]=Truesi=sj

算法伪代码:

  • 输入:字符串 S S S
  • 输出:最长回文子串 S ′ S' S
longestPalindrome(S)
	n <- S.length;
	dp <- new boolean[n][n]
	start <- 1;
	maxL <- 1;
	if n <= 1 Then return S;
	for i <-1 to n
		dp[i][i] <- True;
	for i <-1 to n - 1
		if S[i] = S[i + 1] Then 
			dp[i][i + 1] <- True;
			start <- i;
			maxL <- 2;
	for gap <- 2 to n - 1
		for i <- 1 to n - gap - i
			j <- i + gap;
			if dp[i + 1][j - 1] && S[i] = S[j] Then
				dp[i][j] <- True;
				start <- i;
				maxL <- gap + 1;
	return S.subString(start, start + gap);

时间复杂度分析:

  • 输入规模: n n n
  • 复杂度: O ( n 2 ) O(n^2) O(n2)

4、答:
定义: d p [ i ] [ j ] 记 录 到 达 网 格 A 第 i 行 第 j 列 , 最 短 路 径 dp[i][j] 记录到达网格A第i行第j列,最短路径 dp[i][j]Aij,则有

递推方程:

d p [ i ] [ j ] = A [ i ] [ j ] i f    i = 1 且 j = 1 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + A [ i ] [ j ] i f    j = 1 且 i > = 2 d p [ i ] [ j ] = d p [ i ] [ j − 1 ] + A [ i ] [ j ] i f    i = 1 且 j > = 2 d p [ i ] [ j ] = M i n ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + A [ i ] [ j ] dp[i][j] = A[i][j] \quad if \; i = 1 且 j = 1\\ dp[i][j] = dp[i - 1][j] + A[i][j] \quad if \; j = 1 且 i >=2\\ dp[i][j] = dp[i][j - 1] + A[i][j] \quad if \; i = 1 且 j >= 2\\ dp[i][j] = Min(dp[i - 1][j], dp[i][j - 1]) + A[i][j] dp[i][j]=A[i][j]ifi=1j=1dp[i][j]=dp[i1][j]+A[i][j]ifj=1i>=2dp[i][j]=dp[i][j1]+A[i][j]ifi=1j>=2dp[i][j]=Min(dp[i1][j],dp[i][j1])+A[i][j]

算法伪代码:

  • 输入:网格 A [ 1... m ] [ 1... n ] A[1...m][1...n] A[1...m][1...n]
  • 输出:到达网格第m行第n列的最短路径
findPath(A, m, n)
	dp <- new int[m][n];
	dp[1][1] <- A[1][1];
	path <- new Stack()
	for i <- 2 to m
		dp[i][1] <- dp[i - 1][1] + A[i][1];
	for j <- 2 to n
		dp[1][j] <- dp[1][j - 1] + A[1][j];
	for i <- 2 to m
		for j <- 2 to n
			dp[i][j] <- Min(dp[i - 1][j],dp[i][j - 1]) + A[i][j];
	i <- m; j <- n;
	while i >= 1 && j >= 1
		d <- dp[i][j] - A[i][j]
		if i > 1 && dp[i - 1][j] == d Then
			path.push(DOWN);
		else
			path.push(RIGHT);
	return path;

时间复杂度分析:

  • 输入规模: m n mn mn
  • 复杂度: O ( m n ) O(mn) O(mn)

5、答:
定义: d p [ i ] [ j ] 为 i 时 刻 j 位 置 可 以 收 到 得 最 多 馅 饼 数 dp[i][j]为i时刻j位置可以收到得最多馅饼数 dp[i][j]ij

递推方程:
d p [ i ] [ j ] = P [ i ] [ j ] i f    i = 1 且 j = 4 , 5 , 6 d p [ i ] [ j ] = M a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j + 1 ] ) + P [ i ] [ j ] dp[i][j] = P[i][j] \quad if \; i = 1 且 j = 4, 5, 6\\ dp[i][j] = Max(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + P[i][j] dp[i][j]=P[i][j]ifi=1j=4,5,6dp[i][j]=Max(dp[i1][j],dp[i1][j1],dp[i1][j+1])+P[i][j]

算法伪代码:

  • 输入: 数 组 P , P [ i ] [ j ] 表 示 i 时 刻 j 位 置 落 下 得 馅 饼 数 数组P,P[i][j]表示i时刻j位置落下得馅饼数 PP[i][j]ij
  • 输出:可以获得最多得馅饼数
getPie(P)
	t <- P.length;
	dp <- new int[13];
	dp[-1] <- 0; dp[11] <- 0; 
	dp[4] <- P[1][4];dp[5] <- P[1][5];dp[6] <- P[1][6];
	start <- 3;
	end <- 7;
	for i <- 2 to t
		start <- Max(--start, 0);
		end <- Min(++end, 10);
		for j <- start to end
			dp[j] <- Max(dp[j],dp[j - 1], dp[j + 1]) + P[i][j];
	return Max(dp);

时间复杂度分析:

  • 输入规模: 11 n 11n 11n
  • 复杂度: O ( n ) O(n) O(n)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Geant4 中,Hit 是用于存储粒子在探测器中击中位置和能量等信息的类。您可以使用以下步骤来使用 Hit: 1. 创建一个自定义的 Hit 类,例如 MyHit。您可以在 MyHit 类中定义需要存储的信息,例如能量、位置等。例如: ```cpp class MyHit : public G4VHit { public: MyHit(); virtual ~MyHit(); // setter methods void SetEnergy(G4double energy); void SetPosition(G4ThreeVector position); // getter methods G4double GetEnergy() const; G4ThreeVector GetPosition() const; private: G4double fEnergy; G4ThreeVector fPosition; }; ``` 2. 在您的探测器中定义 HitsCollection。例如,如果您的探测器名称为 "MyDetector",则可以使用以下代码定义 MyHitsCollection: ```cpp G4int MyDetector::fHitsCollectionID = -1; MyDetector::MyDetector() : G4VSensitiveDetector("MyDetector") { // ... fHitsCollection = new MyHitsCollection(SensitiveDetectorName, collectionName[0]); } void MyDetector::Initialize(G4HCofThisEvent* HCE) { // ... if (fHitsCollectionID < 0) { fHitsCollectionID = GetCollectionID(0); } HCE->AddHitsCollection(fHitsCollectionID, fHitsCollection); } ``` 请注意,这里的 "MyHitsCollection" 和 "MyDetector" 都是您自己定义的类名。您需要根据您的应用程序自定义这些类,并将它们与 HitsCollection 关联起来。 3. 在您的探测器中实现 ProcessHits() 方法,将击中信息存储到 HitsCollection 中。例如: ```cpp void MyDetector::ProcessHits(G4Step* step, G4TouchableHistory*) { MyHit* hit = new MyHit(); hit->SetEnergy(step->GetTotalEnergyDeposit()); hit->SetPosition(step->GetPostStepPoint()->GetPosition()); fHitsCollection->insert(hit); } ``` 4. 在事件结束后,您可以从 HitsCollection 中获取每个 hit,并从中提取信息。例如,可以使用以下代码获取每个 hit 的位置和能量: ```cpp for (size_t i = 0; i < hitsCollection->GetSize(); i++) { MyHit* hit = static_cast<MyHit*>(hitsCollection->GetHit(i)); G4double energy = hit->GetEnergy(); G4ThreeVector position = hit->GetPosition(); // do something with energy and position } ``` 请注意,这里的 "MyHit" 和 "MyHitsCollection" 都是您自己定义的类名。您需要根据您的应用程序自定义这些类,并将其与 HitsCollection 关联起来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值