AISing Programming Contest 2021(AtCoder Beginner Contest 202)D - aab aba baa

Posted TURNINING

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AISing Programming Contest 2021(AtCoder Beginner Contest 202)D - aab aba baa相关的知识,希望对你有一定的参考价值。

传送门
这是个什么神仙题

题意:一个字符串由A个‘a’,B个‘b’,要求字典序第K大的数。

思路:我们可以根据K的值来确定第i位是放‘a’还是放‘b’。设C(i,j)为放i个‘a’,j个‘b’的方案数。
当K <= C(i-1, j)时,我们可以确定这里是放‘a’的,因为所有以a开头的都小于b开头的。
当K > C(i-1, j)时,这里放b。
当我们确定第i位放a时我们要找的就是C(i-1,j)中的第K大
放b时我们要找的就是C(i,j-1)中的第k - C(i-1,j)大。
因为数据小C(i,j)可以用dp算。

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int maxn = 30 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 9973;
const ull B = 100000007;

ll dp[maxn][maxn];

string dfs(int A, int B, ll k) {
    if(A == 0) return string(B, 'b');
    if(B == 0) return string(A, 'a');
    if(dp[A-1][B] >= k) return "a" + dfs(A-1, B, k);
    else return "b" + dfs(A, B-1, k - dp[A-1][B]);
}

void solve() {
    int a, b;
    ll k;
    cin >> a >> b >> k;
    dp[0][0] = 1;
    for(int i = 0; i <= a; i++) {
        for(int j = 0; j <= b; j++) {
            if(j >= 1) dp[i][j] += dp[i][j-1];
            if(i >= 1) dp[i][j] += dp[i-1][j]; 
        }
    }
    cout << dfs(a, b, k) << endl;
}

int main() {
    //ios::sync_with_stdio(false);
    solve();
    return 0;
}   

以上是关于AISing Programming Contest 2021(AtCoder Beginner Contest 202)D - aab aba baa的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder AISing Programming Contest 2019 Task D. Nearest Card Game

AISing Programming Contest 2021(AtCoder Beginner Contest 202)ABCD

AISing Programming Contest 2021(AtCoder Beginner Contest 202)ABCD

AISing Programming Contest 2021(AtCoder Beginner Contest 202) E

AISing Programming Contest 2021(AtCoder Beginner Contest 202)(补题)

AISing Programming Contest 2021(AtCoder Beginner Contest 202)D - aab aba baa