zoukankan      html  css  js  c++  java
  • [CF1183H] Subsequences (hard version)

    Description

    你有一个长度为 $ n le 100 $ 的字符串。对于一个长度为 $ m $ 的子序列,选出它的花费是 $ n-m $,也就是你需要删掉的字符数量。你的任务是选出 $ k $ 个本质不同的子序列,使得总花费最小。输出这个最小花费。如果选不出 $ k $ 个,输出 $ -1 $。

    Solution

    (pre[i]) 表示 (i) 的前驱位置,设 (f[i][j]) 表示前 (i) 个字符,长度为 (j) 的本质不同子串的数量,则

    [f[i][j]=f[i-1][j]+f[i-1][j-1]-f[pre[i]-1][j-1] ]

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 105;
    
    int n,k,pre[N],last[N],f[N][N];
    char s[N];
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>k>>s+1;
        for(int i=1;i<=n;i++) {
            pre[i]=last[s[i]-'a'];
            last[s[i]-'a']=i;
        }
        for(int i=0;i<=n;i++) f[i][0]=1;
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=i;j++) {
                f[i][j]=f[i-1][j]+f[i-1][j-1]-(pre[i]?f[pre[i]-1][j-1]:0);
            }
        }
        int ans=0;
        for(int i=n;i>=0;--i) {
            if(f[n][i]<=k) {
                ans+=f[n][i]*(n-i);
                k-=f[n][i];
            }
            else {
                ans+=k*(n-i);
                k=0;
                break;
            }
        }
        if(k) cout<<-1;
        else cout<<ans;
    }
    
  • 相关阅读:
    Leetcode Binary Tree Preorder Traversal
    Leetcode Minimum Depth of Binary Tree
    Leetcode 148. Sort List
    Leetcode 61. Rotate List
    Leetcode 86. Partition List
    Leetcode 21. Merge Two Sorted Lists
    Leetcode 143. Reorder List
    J2EE项目应用开发过程中的易错点
    JNDI初认识
    奔腾的代码
  • 原文地址:https://www.cnblogs.com/mollnn/p/12857076.html
Copyright © 2011-2022 走看看