P1280 尼克的任务
很久就过掉了,补个题解。
先思考:设\(dp[i]\)为时刻\(i\)获得的最大空闲时间,那么:
\[dp[i] =
\begin{cases}
dp[i - 1] + 1 & \texttt{don't have work}\\
\max \{dp[i + T[s]\} & \texttt{have work at } \color{red}{\texttt{s}}
\end{cases}
\]
会发现,\(dp[i + T[s]]\)需要先计算,所以要从\(n\)到\(1\)计算,递推式也要改一改:
\[dp[i] =
\begin{cases}
dp[i + 1] + 1 & \texttt{don't have work}\\
\max \{dp[i + T[s]\} & \texttt{have work at } \color{red}{\texttt{s}}
\end{cases}
\]
时间复杂度显然是\(O(n)\)的
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int dp[N];
int n, k;
vector<int> T[N];
int main(void)
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= k; i++)
{
int s, t;
scanf("%d%d", &s, &t);
T[s].push_back(t);
}
for (int i = n; i >= 1; i--)
{
if (T[i].size() == 0)
dp[i] = dp[i + 1] + 1;
else
{
for (int j = 0; j < T[i].size(); j++)
dp[i] = max(dp[i], dp[i + T[i][j]]);
}
}
printf("%d\n", dp[1]);
return 0;
}