用c++完成这道题:在一个排列中,一个折点是指排列中的一个元素,它同时小于两边的元素,或者同时大于两边的元素。 对于一个 1 ∼ nn 的排列,如果可以将这个排列中包含 tt 个折点,则它称为一个 t + 1t+1 单调序列。 例如,排列 (1,4,2,3) 是一个 3 单调序列,其中 4 和 2 都是折点。 给定 nn 和 kk,请问 1 ∼ nn 的所有排列中有多少个 kk 单调队列?
时间: 2023-06-10 20:03:53 浏览: 118
C++ 先对数组排序,在进行折半查找
我理解你的问题是要求n个数中,有多少个排列可以成为k单调序列。
解法很经典,可以用动态规划完成。具体思路如下:
设dp[i][j]表示前i个数中,以第i个数结尾的j单调数列的总数。则可以得到状态转移方程:
当j=1时,dp[i][1]=1;
当j>=2时,dp[i][j]=∑dp[k][j-1],其中k<i且nums[k]<nums[i],也就是说,前i个数中小于nums[i]的数都可以作为倒数第二个数,只要前面的数可以构成j-1单调数列即可。
最终答案为∑dp[i][k],i从1到n。
C语言代码如下:
```c
#include <stdio.h>
#include <string.h>
int dp[1010][1010];
int main() {
int n, k;
scanf("%d%d", &n, &k);
memset(dp, 0, sizeof(dp));
for(int i=1; i<=n; i++) {
dp[i][1] = 1;
for(int j=2; j<=k; j++) {
for(int l=1; l<i; l++) {
if(nums[l]<nums[i])
dp[i][j] += dp[l][j-1];
}
}
}
int ans = 0;
for(int i=1; i<=n; i++)
ans += dp[i][k];
printf("%d", ans);
return 0;
}
```
阅读全文