動態規劃解按摩師的最長預約時間
阿新 • • 發佈:2020-11-16
問題描述:
一名有名的按摩師會收到源源不斷的預約請求,每個預約都可以選擇接或者不接。在每次預約服務之間要有休息時間,因此她不能接受相鄰時間的預約。
給定一個預約請求序列,替按摩師找到最優的預約集合(總預約時間最長),返回總的分鐘數。
示例1
輸入 [1,2,3,1]
輸出 4
解釋 選擇1號和3號預約,總時長1+3=4
示例2
輸入 [2,7,9,3,1]
輸出 12
解釋 選擇1、3、5號預約,總時長2+9+1=12
示例3
輸入 [2,1,4,5,3,1,1,3]
輸出 12
解釋 選擇1、3、5、8號預約,總時長2+4+3+3=12
動態規劃解決
陣列中的值表示的是預約時間,
按摩師可以選擇接或者不接,
如果前一個接了,那麼下一個肯定是不能接的,
因為按摩師不能接相鄰的兩次預約。
如果上一次沒接,那麼下一個可以選擇接也可以選擇不接。
這裡可以定義一個二維陣列dp[length][2],其中dp[i][0]表示第i+1個預約沒有接的最長總預約時間,dp[i][1]表示的是第i+1個預約接了的最長總預約時間。
遞推公式
dp[i][0] = max(dp[i-1][0],dp[i-1][1])
dp[i][1] = dp[i-1][0] + arr[i]
dp[0][0] = 0
dp[0][1] = arr[0]
程式碼詳情
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; int main() { //int arr[] = {2,7,9,2,1}; //int len = sizeof(arr)/sizeof(arr[0]); int n=0; cout<<"序列長度:"; cin >> n; int arr[n]; cout<<"序列:"; for(int i=0;i<n;i++){ cin>>arr[i]; } int len = n; int dp[len][2]; dp[0][0] = 0; dp[0][1] = arr[0]; for(int i=1;i<len;i++){ dp[i][0] = max(dp[i-1][0],dp[i-1][1]); dp[i][1] = dp[i-1][0] + arr[i]; } for(int i=0;i<2;i++){ for(int j=0;j<len;j++){ cout<<dp[j][i]<<" "; } cout<<endl; } return 0; }
例項2:動態規劃dp表格
0 | 2 | 7 | 11 | 11 |
---|---|---|---|---|
2 | 7 | 11 | 9 | 11 |