Codeforcecs1183H Subsequence (hard version) seeking the number of essentially different character strings sequence

Topic links: https://www.luogu.org/problem/CF1183H

Meaning of the questions: to give you a length n (100) string, you need to find k (1e12) it is essentially different sequences, and did not find out the cost of a sequence of n-len (sequence), The minimum spend requirements

Analysis: Obviously you want to spend a minimum, they begin to look for the maximum length of the sequences, is transformed into a different nature to find the length of each sub-sequence of how many

We DP [i] [j] denotes the i-th character from the beginning, the number of sequences of length j of how many.

Then direct transfer will be repeated, such as baa, you will find two ba

So for every i, we use a vis array tag, just a transfer of the same character that first appeared

In order to ensure that the sequence is a plus, we first dimension is a length Len dp

After greedy to find the answer

Note: Because the empty string is a sequence, initialization of i = 0 have to consider, and after each non-empty sequence actually contains the equivalent of an empty string, the cycle began when solving dp from i = 0, Finally, when looking for answers directly from dp [0] [len] to dp [0] [1] a

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=2e5+7;
const int N=1e4;
char s[110];
ll dp[210][210];
int vis[100];
int main(){
    int n;ll k;cin>>n>>k;
    k--;// first option full string without spending 
    Scanf ( " % S " , S + . 1 );
     for ( int I = 0 ; I <= n-; I ++) DP [I] [ . 1 ] = . 1 ;
     for ( int len = 2 ; len <= n-; len ++ ) {
         for ( int I = 0 ; I <= n-; I ++ ) { 
            Memset (VIS, 0 , the sizeof (VIS));
             for ( int K = I + . 1 ; K <= n- ; K ++ ) {
                 IF (VIS [S [K] -!'a']){
                    vis[s[k]-'a']=1;
                    dp[i][len]+=dp[k][len-1];
                }
            }
        }
    }
    ll ans=0;
    //cout<<dp[0][4]<<" 233\n";
    for(int len=n;len>0&&k!=0;len--){
        if(dp[0][len]<=k){
            k-=dp[0][len];
            ans+=1ll*(n+1-len)*dp[0][len];
        }
        else{
            ans+=1ll*(n+1-len)*k;
            k=0;
        }
    }
    if(k>0)printf("-1\n");
    else printf("%I64d\n",ans);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/qingjiuling/p/11622034.html