首页 > 其他 > 详细

The Preliminary Contest for ICPC Asia Shanghai 2019 F. Rhyme scheme(dp)

时间:2019-09-21 20:05:06      阅读:75      评论:0      收藏:0      [点我收藏+]

技术分享图片

 

 技术分享图片

 

 题意:给你一个n和k 要你找到长度为n 字典序第k小的字符串 定义一个字符串合法:第i的字符的范围只能是前i-1个字符中的最大值+1

思路:我们dp[n][i][j]表示长度为n 在第i位 最大值为j的序列有多少个 随后我们可以直接模仿找第k大一样找到第k个字符串

技术分享图片
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const int N = 1e6+7;
typedef long long ll;
typedef __int128 bll;
const ll mod = 998244353;
using namespace std;
inline __int128 read() {
     __int128 x=0,f=1;
     char ch=getchar();
     while(ch<0||ch>9) {
         if(ch==-)
             f=-1;
         ch=getchar();
     }
     while(ch>=0&&ch<=9) {
         x=x*10+ch-0;
         ch=getchar();
     }
     return x*f;
}
inline void print(__int128 x)
{    
   if(x<0){putchar(-);x=-x;}
   if(x>9) print(x/10);
   putchar(x%10+0);
}
bll dp[30][30][30];
char v[30];
bll dfs(int len,int now,int mx){
    if(now==len){
        dp[len][now][mx]=1;
        return dp[len][now][mx];
    }
    if(dp[len][now][mx]!=-1) return dp[len][now][mx];
    bll ans=0;
    for(int i=1;i<=min(mx+1,26);i++){
        if(i<=mx){
            ans+=dfs(len,now+1,mx);
        }else{
            ans+=dfs(len,now+1,i);
        }
    }
    dp[len][now][mx]=ans;
    return ans;
}
int main(){
//    ios::sync_with_stdio(false);
//    cin.tie(0); cout.tie(0);
    int t; scanf("%d",&t);
    for(int i=0;i<30;i++)
        for(int j=0;j<30;j++)
            for(int k=0;k<30;k++)
                dp[i][j][k]=-1;
    for(int i=1;i<=26;i++)
        dfs(i,1,1);
    int w=0;
//    print(dp[3][1][1]);
    while(t--){
        int n; scanf("%d",&n);
        bll k; k=read();
        int mx=1;
        printf("Case #%d: ",++w);
        for(int i=1;i<=n;i++){
            v[i]=A; 
            for(int j=1;j<=mx+1;j++){
                //cout<<k<<" "<<dp[n][i][j]<<endl;
                int p=max(mx,j);
                if(dp[n][i][p]>=k){
                //    mx=max(mx,j);
                    v[i]=char(j+A-1);
                    //putchar(‘A‘ + j - 1);
                    mx=max(mx,p);
                //    cout<<j<<endl;
                    break;
                }else{
                    k-=dp[n][i][p];
                }
            }
        }
        for(int i=1;i<=n;i++)
            printf("%c",v[i]);
        puts("");
    }
    return 0;
}
View Code

 

The Preliminary Contest for ICPC Asia Shanghai 2019 F. Rhyme scheme(dp)

原文:https://www.cnblogs.com/wmj6/p/11564257.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!