用C++解决以下问题使用一维DP数组解决多年过去后Su_Zipei 成为了一名NOI赛场的工作人员一年一度的NOI到了这次他负责分发纸质题面从一侧的办公室中拿出 n 个题册要发给 n 名同学最后需要回到办公室注意他只能走一个来回也就是说如果一名同学在 Su_Zipei 从 1 到 n 的过程中没有拿到题册那这名同学必须在 Su_Zipei 从 n 到 1 的过程中拿到题册。这 n 名同学坐成一排离
问题可以转化为求解最长递增子序列的问题。我们可以将每个同学的开心值作为序列中的元素,然后通过动态规划求解最长递增子序列的长度。
具体的动态规划思路如下:
- 创建一个长度为n的一维DP数组dp,用来记录以第i个同学结尾的最长递增子序列的长度。
- 初始化dp数组的所有元素为1,表示每个同学自己构成的最长递增子序列的长度为1。
- 遍历每个同学i,从1到n,对于每个同学i,再遍历前面的同学j,从1到i-1。
- 如果第j个同学的开心值小于第i个同学的开心值,即H[j] < H[i],则可以将第i个同学加入到第j个同学的最长递增子序列中,此时更新dp[i]为dp[j]+1。
- 在遍历过程中,记录最大的dp[i]值,即为最长递增子序列的长度。
- 最终的答案为n减去最长递增子序列的长度。
下面是使用C++实现的代码:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> H(n);
for (int i = 0; i < n; i++) {
cin >> H[i];
}
vector<int> dp(n, 1);
int maxLen = 1;
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (H[j] < H[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
maxLen = max(maxLen, dp[i]);
}
int ans = n - maxLen;
cout << ans << endl;
return 0;
}
输入样例:
5
2 4 3 5 1
输出样例:
2
解释:最长递增子序列为2 4 5,所以答案为5-3=2
原文地址: http://www.cveoy.top/t/topic/iovt 著作权归作者所有。请勿转载和采集!