字节--房间传送门
字節–房間傳送門
文章目錄
- 字節--房間傳送門
- 一、題目描述
- 二、分析
- 三、代碼
一、題目描述
存在n+1個房間,每個房間依次為房間1 2 3…i,每個房間都存在一個傳送門,i房間的傳送門可以把人傳送到房間pi(1<=pi<=i),現在路人甲從房間1開始出發(當前房間1即第一次訪問),每次移動他有兩種移動策略:
- A. 如果訪問過當前房間 i 偶數次,那么下一次移動到房間i+1;
- B. 如果訪問過當前房間 i 奇數次,那么移動到房間pi;
現在路人甲想知道移動到房間n+1一共需要多少次移動;
- 輸入描述:
- 輸出描述:
二、分析
- 仔細分析 1<=pi<=i 知道用動態規劃做。
- 因為pi的取值范圍為1到i,說明在走到i房間時,如果需要傳送,那么傳送的房間位置要么就在當前房間,要么就在當前房間位置之前的房間
- 因為傳送只會后退,前進的唯一方式是偶數次到達某個房間后,+1到達下一個房間,不能跳躍
- 所以如果成功到達i門,那么i門前面所有門都走過并且經過偶數次(偶數次并不是2次)(反正法也可以證明)
- 如果當大imen,那么此時i門前面的所有門肯定是已經到達偶數次了
- 如果到達i門需要移動的次數為dp[i],那么dp[i] = dp[i - 1] + 第二次到達i - 1 + 1;;
- 意思就是到達i門的移動次數等于到達i - 1門的移動次數 + 1;那么到達i - 1門的移動次數又怎么計算呢?到達i - 1門的移動次數就等于dp[i - 1] + 第二次到達i - 1的次數
- 第一次到達i-1門后再走一步會回到p[i-1],此時p[i-1]門到達奇數次,其他所有門到達偶數次
- 這和第一次到達p[i-1]門的情況完全相同,所以從p[i-1]門回到i-1門,需要dp[i-1]-dp[p[i-1]]
- 所以dp[i] = dp[i-1] + dp[i-1] - dp[p[i-1]] + 1 + 1 ==》dp[i] = 2 * dp[i-1] - dp[p[i-1]] + 2
三、代碼
#include <iostream> using namespace std;long long p[1001], dp[1001], n; const long long mod = 1e9?+?7;int main () {cin >> n;for (int i = 1; i<= n; ++i) cin >> p[i];for (int i = 2; i <= n + 1; ++i)dp[i] = (2 * dp[i - 1] - dp[p[i - 1]] + 2) % mod;cout << (dp[n + 1] < 0 ? dp[n + 1] + mod : dp[n + 1]);return 0; }總結