zoukankan      html  css  js  c++  java
  • Codeforces1065G Fibonacci Suffix 【递推】【二分答案】

    题目分析:

    首先为了简便起见我们把前$15$的答案找出来,免得我们还要特判$200$以内之类的麻烦事。

    然后我们从$16$开始递推。考虑猜测第i位是$0$还是$1$(这本质上是个二分)。一开始先猜是$1$,然后求是$0$的有多少个,与当前的$k$判断确认$0$和$1$。

    然后考虑到某种情况就不输出的情况,实际上就是末尾的这个$ans$正好合法。

    然后递推的时候除了将两个串原本出现的加起来,还要考虑拼接的时候多出的。可以预处理也可以边$dp$边做。

    不预处理的暴力做时间是$O(mn^3)$(过不了)

    预处理的暴力做是$O(mn^2)$

    不预处理的KMP是$O(mn^2)$

    预处理的KMP是$O(mn)$。

    自行选择。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n,m;long long k;
     5 
     6 string str[17],suf[2010];
     7 
     8 long long f[250],d[250],h[250],qy[2][2];
     9 string p[2],s[2];
    10 string ans;
    11 
    12 int cmp(string alpha,string beta){
    13     for(int i=0;i<min(alpha.length(),beta.length());i++){
    14     if(alpha[i] == beta[i]) continue;
    15     if(alpha[i] < beta[i]) return 1;
    16     else return 0;
    17     }
    18     return alpha.length()<beta.length();
    19 }
    20 
    21 int Try(string a){
    22     int res = 0;
    23     for(int i=0;i<a.length();i++){
    24     if(i+ans.length()-1 >= a.length()) break;
    25     int flag = true;
    26     for(int j=0;j<ans.length();j++){
    27         if(a[i+j] != ans[j])flag = false;
    28     }
    29     res += flag;
    30     }
    31     return res;
    32 }
    33 
    34 long long solve(){//200
    35     //match 200*200
    36     int len = ans.length();
    37     memset(d,0,sizeof(d));
    38     memset(h,0,sizeof(h));
    39     memset(qy,0,sizeof(qy));
    40     p[0].clear();p[1].clear();s[0].clear();s[1].clear();
    41     d[14] = h[14] = 0; d[15] = h[15] = 1;
    42     for(int i=0;i<len-1;i++) p[0].push_back(str[14][i]),p[1].push_back(str[15][i]);
    43     for(int i=1;i<=len-1;i++) s[0].push_back(str[14][str[14].length()-len+i]);
    44     for(int i=1;i<=len-1;i++) s[1].push_back(str[15][str[15].length()-len+i]);
    45     for(int i=0;i<2;i++) for(int j=0;j<2;j++) qy[i][j] = Try(p[i]+s[j]);
    46 
    47     f[14] = Try(str[14]); f[15] = Try(str[15]);
    48     
    49     for(int i=16;i<=n;i++){//200
    50     h[i] = h[i-1]; //suf
    51     d[i] = d[i-2]; //pre
    52     f[i] = f[i-1]+f[i-2];
    53     f[i] += qy[d[i]][h[i]];
    54     if(f[i] > 1e18) return f[i];//return now
    55     }
    56     return f[n];
    57 }
    58 
    59 int main(){
    60     scanf("%d%lld%d",&n,&k,&m);
    61     str[0] = "0"; str[1] = "1";
    62     for(int i=2;i<=15;i++) str[i] = str[i-2]+str[i-1];
    63     if(n <= 15){
    64     for(int i=0;i<str[n].length();i++){
    65         for(int j=i;j<str[n].length();j++) suf[i+1].push_back(str[n][j]);
    66     }
    67     sort(suf+1,suf+str[n].length()+1,cmp);
    68     for(int i=0;i<min(m,(int)suf[k].length());i++) printf("%c",suf[k][i]);
    69     return 0;
    70     }else{
    71     for(int i=1;i<=m;i++){
    72         ans.push_back('0');
    73         long long z = solve();
    74         if(z < k){ k -= z; ans.pop_back(); ans.push_back('1'); }
    75         int flag = 1;
    76         for(int i=suf[n].length()-ans.length(),j=0;i<suf[n].length();i++){
    77         if(ans[j] != suf[n][i]) flag = false;
    78         j++;
    79         }
    80         k -= flag;
    81         if(k == 0){
    82         for(int i=0;i<ans.length();i++) printf("%c",ans[i]);
    83         return 0;
    84         }
    85     }
    86     for(int i=0;i<ans.length();i++) printf("%c",ans[i]);
    87     }
    88     
    89     return 0;
    90 }
  • 相关阅读:
    Spring Boot中只能有一个WebMvcConfigurationSupport配置类
    【原创】(六)Linux进程调度-实时调度器
    【原创】(二)Linux进程调度器-CPU负载
    【原创】(十二)Linux内存管理之vmap与vmalloc
    【原创】(十一)Linux内存管理slub分配器
    【原创】(七)Linux内存管理
    【原创】(五)Linux内存管理zone_sizes_init
    【原创】(三)Linux paging_init解析
    【原创】(二)Linux物理内存初始化
    【原创】(一)ARMv8 MMU及Linux页表映射
  • 原文地址:https://www.cnblogs.com/Menhera/p/9837502.html
Copyright © 2011-2022 走看看