zoukankan      html  css  js  c++  java
  • 使字符串有序的最少操作次数

    题意

    给你一个字符串 s (下标从 0 开始)。你需要对 s 执行以下操作直到它变为一个有序字符串:
    找到 最大下标 i ,使得 1 <= i < s.length 且 s[i] < s[i - 1] 。
    找到 最大下标 j ,使得 i <= j < s.length 且对于所有在闭区间 [i, j] 之间的 k 都有 s[k] < s[i - 1] 。
    交换下标为 i - 1​​​​ 和 j​​​​ 处的两个字符。
    将下标 i 开始的字符串后缀反转。
    请你返回将字符串变成有序的最少操作次数。由于答案可能会很大,请返回它对 109 + 7 取余 的结果。

    解析

    实质上是求一个全排列,使其最终有序。例如cba->cab->bca->bac->acb->abc
    本质上是组合计数。确定具有相同前缀,比当前字符小的排列数目。如cba以cb为前缀的只有cba,以c为前缀比b小的前缀只有a,a后面的位置求组合数是C(1,1)。
    设字符串p,那么p后的可能方案满足字符s<p,每个s后的组合数为C(z_a,a1)C(z_a-a1,a2)()...()
    代码如下:

    #define ll long long
    class Solution {
    public:
    //求全排列
        const int mod=1e9+7;
        int c[3050][3050],cnt[26];
        void init(int n)
        {   
            c[0][0]=1;
            for(int i=1;i<=n;i++){
                c[i][0]=c[i][i]=1;
                for(int j=1;j<i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
            }
        }
        ll find(int n,int m)
        {
            if(n==0) return 1ll;
            if(m==0) return 1ll;
            if(m>n)  return 1ll;
            return c[n][m];
        }
        int makeStringSorted(string s) {
            int n=s.size();
            init(n);
            ll ans=0;
            for(int i=n-1;i>=0;i--){
                int val=s[i]-'a';
                cnt[val]++;
                for(int c=val-1;c>=0;c--){ //当前位填c,c<val 在剩余的字母中寻找填入
                    if(cnt[c]==0) continue;
                    cnt[c]-=1;
                    int left=n-i-1;
                    ll cur=1;
                    for(int j=0;j<26;j++){ //剩余的位置填入a-z的字母
                        cur=cur*find(left,cnt[j])%mod;
                        left-=cnt[j];
                    }
                    cnt[c]+=1;
                    ans=(ans+cur)%mod;
                }
            }
            return ans;
        }
    };
    
  • 相关阅读:
    平面点集最佳平面
    快速变幻AABB的顶点
    惯性坐标系
    Grapher
    Grapher
    射线到直线方程的转换
    两个运动球的相交性测试
    射线和球的相交性
    Glow Shader
    Shder中实现TintColor
  • 原文地址:https://www.cnblogs.com/flightless/p/14715736.html
Copyright © 2011-2022 走看看