牛客编程巅峰赛S1第9场 - 王者 C 牛牛摆木棒

牛牛摆木棒

https://ac.nowcoder.com/acm/contest/6781/C

题意:求n的排列中第k个波浪形的排列

牛客巅峰赛系列里面少有的,还算有一点意思的题目(没错我就是在喷),可惜考场上时间不太够,想出来没码完(好吧确实是因为我一开始把找第k个的部分写麻烦了)。

首先来考虑求满足条件序列数量的问题,记表示长度为n,以k开头的先上升或先下降的序列数量。


预处理出来这个dp数组之后,按照跟dp相同的思路逐位确定最终答案即可。

#define ll long long 
class Solution {
public:
    /**
     * 
     * @param n int整型 木棒的个数
     * @param k long长整型 第k个排列
     * @return int整型vector
     */
    ll dp[30][30][2];
    vector<int> ask(int n, int now, ll k, int flag){
        vector<int> res, _res;
        if (n>1){
            if (flag == 0){
                for (int j = 1; j < now; j++){
                    long long tmp = dp[n-1][j][1];
                    if (k > tmp) k-=tmp;else{
                        res = ask(n-1, j, k, 1);
                        break;
                    }
                }
            }else{
                for (int j = now+1; j <= n; j++){
                    long long tmp = dp[n-1][j-1][0];
                    if (k > tmp) k-=tmp;else{
                        res = ask(n-1, j-1, k, 0);
                        break;
                    }
                }
            }
        }
        for (int i = 0; i < n-1; i++) res[i] += res[i] >= now;
        _res.push_back(now);
        for (int i = 0; i < n-1; i++) _res.push_back(res[i]);
        return _res;
    }
    vector<int> stick(int n, ll k) {
        memset(dp, 0, sizeof(dp));
        dp[1][1][0] = dp[1][1][1] = 1;
        for (int i = 2; i <= n; i++){
            for (int j = 1; j <= i; j++){
                for (int k = 1; k < j; k++){
                    dp[i][j][0] += dp[i-1][k][1];
                }
                for (int k = j+1; k <= i; k++){
                    dp[i][j][1] += dp[i-1][k-1][0];
                }
            }
        }
        for (int a = 1; a <= n; a++){
            if (dp[n][a][0] >= k){
                return ask(n, a, k, 0);
            }else k-=dp[n][a][0];
            if (dp[n][a][1] >= k){
                return ask(n, a, k, 1);
            }else k-=dp[n][a][1];
        }
    }
};
全部评论
萌新对这个dp感到疑惑,有几个问题想要请教大佬,希望能得到答复 1.这样的转移方程不会产生重复的情况吗。比如dp[4][2][1]的答案里有一组解是(2,3,1,4) 那么在更新dp[5][3][0]的时候为啥不会产生(3,2,3,1,4)这种解呀。。 2.还有就是这里的转移方程为什么是k-1,而不是k。 dp[i][j][1] += dp[i-1][k-1][0];
点赞 回复 分享
发布于 2020-08-07 00:36

相关推荐

我是没经验的毕业生,这啥情况啊会不会是hr在刷kpi
JamesGosli...:字节boss属于是群发了,我都快入职字节了,其他部门还在和我boss打招呼
点赞 评论 收藏
分享
06-11 17:39
门头沟学院 Java
小呆呆的大鼻涕:卧槽,用户彻底怒了
点赞 评论 收藏
分享
05-29 20:34
门头沟学院 C++
KarlAllen:得做好直接春招的准备。学历差的话,一是面试要求会比学历好的严格不少,二是就算面试通过了也会被排序。总之暑期和秋招对于学历差的就是及其不友好
无实习如何秋招上岸
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-04 18:02
好不容易拿到了字节Offer,鼠鼠做后端的,但家里人觉得可能被裁员不稳定,让鼠鼠去投国企,现在好纠结到底该咋选
文档传偷助手:该投就投吧,不过建议别放弃offer 拿到手里的才是最好的
投递字节跳动等公司8个岗位
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务