ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #820 (Div. 3) G. Cut Substrings dp计数

2022-09-14 23:31:05  阅读:207  来源: 互联网

标签:Cut int res Codeforces tot flag size Round define


 https://codeforces.ml/contest/1729/problem/G

https://zhuanlan.zhihu.com/p/563809110

分析:

就是把主串中所有跟子串匹配的位置删掉,问最少删除多少次能够满足主串中不再出现子串,并问满足最少删除次数的方案数有多少个

f[i]:[1,i] 必须删除[i-m+1,i] 的子串,总共的最少删除次数

tot[i]:[1,i] 必须删除[i-m+1,i] 的子串,所有满足最少删除次数的方案数

状态转移:f[i] = f[j] + 1;需要删除的情况多了一个

三种情况:

1.子串前缀和后缀不相等,直接删除主串中所有满足条件的子串就可以了,方案数是1

2.子串前缀和后缀相等,这时候会有重叠,f[i] 不能从所有k 属于[i-m+1,i] 的情况中转移过来 。

3.子串前缀和后缀相等,这时候会有重叠, [j,i] 中如果有k 满足 [k-m+1,k] 是子串,并且 k < i && k - m + 1 > j ,f[i] 不能从这些 j 转移过来,因为它们的情况已经记录到 k 里了,如果再转移,总的删除次数会减少

最后答案:

最后一个满足条件的串内,所有最少次数的方案数累计。

//-------------------------代码----------------------------

#define int ll
const int N = 3000,mod = 1e9+7;
int n,m;

int f[N];
int tot[N];

void solve()
{
    V<int>v; 
    ms(f,inf);ms(tot,0);
    string s,t;
    cin>>s>>t;
    n = s.size(),m = t.size();
    s = ' ' + s;
    v.pb(0);
    for(int i = 1;i + m - 1 <= n;i ++ ) {
        if(s.substr(i,m) == t) v.pb(i + m - 1);
    } 
    f[0] = 0,tot[0] = 1;
    for(int i = 0;i<v.size();i ++ ) {
        for(int j = i - 1;j >= 0;j -- ) {
            if(v[i] - v[j] < m) continue;
            bool flag = 1;
            for(int k = j + 1; k < i ;k ++ ) {
                if(v[k] - v[j] >= m && v[i] - v[k] >= m) {
                    flag = 0;
                }
            }
            if(flag == 0) break;
            if(f[i] > f[j] + 1) {
                f[i] = f[j] + 1;
                tot[i] = tot[j];
            } 
            else if(f[i] == f[j] + 1) {
                tot[i] = (tot[i] + tot[j]) % mod;
            }
         }
    }
    int mi = inf,ans = 0;
    for(int i = 0; i < v.size();i ++ ) {
        if(v.back() - v[i] < m) mi = min(mi,f[i]);
    }
    for(int i = 0;i < v.size();i ++ ) {
        if(v.back() - v[i] < m && f[i] == mi) ans = (ans + tot[i]) % mod;
    }
     cout<<mi<<' '<<ans<<endl; 
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

#include<bits/stdc++.h>#define TLE ios::sync_with_stdio(0),cin.tie(0)#define endl "\n"#define FILE "a"#define pb push_back#define gg exit(0);#define rt return;#define bd cout<<"debug"<<endl;#define db(x) cout<<#x<<':'<<x<<endl;#define dbb(i,a) cout<<#i<<':'<<i<<' '<<#a<<':'<<a<<' '<<endl;#define dbbb(i,a,b) cout<<#i<<':'<<i<<' '<<#a<<':'<<a<<' '<<#b<<':'<<b<<endl;#define TIME cout<<"RuningTime: "<<clock()<<"ms\n";#define YES cout<<"YES"<<endl;#define Yes cout<<"Yes"<<endl;#define NO cout<<"NO"<<endl;#define No cout<<"No"<<endl;#define None cout<<-1<<endl;#define el cout<<endl;#define x first#define y second#define V vector#define fo(i,j,n) for(int i = j;i<=n;i++)#define of(i,n,j) for(int i = n;i>=j;i--)#define fe(i,u) for(int i = h[u];~i;i=ne[i])#define all(a) a.begin(),a.end()#define alll(a) a.begin()+1,a.end()#define ms(a,b) memset(a, b, sizeof(a));#define tr_len(u) (tr[u].r - tr[u].l + 1)#define tr_mid (tr[u].l + tr[u].r >> 1)#define ul (u<<1)#define ur (u<<1|1)#define lowbit(x) (x&-x)#define gcd(a,b) __gcd(a,b)#define CLAP 11243using namespace std;void clapping() {#if CLAP == 1srand(time(NULL)+rand());freopen("a.in","r",stdin);freopen("a.out","w",stdout);//freopen("a.in","w",stdout);#endif}template<class T>inline void read(T &res) {    char c;T flag = 1;    while((c = getchar()) < '0' || c > '9') if(c == '-') flag = -1;res = c - '0';    while((c=getchar())>='0'&&c<='9')res=(res<<1)+(res<<3)+(c^48);res*=flag;}typedef pair<int,int> pii;typedef pair<long,long>pll;typedef long long ll;const int inf = 0x3f3f3f3f;const ll INF = 0x3f3f3f3f3f3f3f3fll;const double eps = 1e-8;int dy[] = {1,0,-1,0,1,1,-1,-1};int dx[] = {0,1,0,-1,1,-1,1,-1};ll qmi(ll a,ll b) {int res = 1;for(;b;b>>=1,a = a * a ) {if(b&1) res = res * a;}return res;}template<class T> T exgcd(T a,T b,T &x,T &y) {if(b == 0) {x = 1;y = 0;return a;}ll d = gcd_ed(b,a%b,y,x);y = y - a / b * x;return d;}template<class T> T qmul(T a,T b,T p) {T res = 0;for(;b;b >>= 1,a = (a + a) % p) {res = (res + a) % p;}return res;}/*文档区

*/void AC(){    ////                       _oo0oo_//                      o8888888o//                      88" . "88//                      (| -_- |)//                      0\  =  /0//                    ___/`---'\___//                  .' \\|     |// './/                 / \\|||  :  |||// \//                / _||||| -:- |||||- \//               |   | \\\  -  /// |   |//               | \_|  ''\---/''  |_/ |//               \  .-\__  '-'  ___/-. ///             ___'. .'  /--.--\  `. .'___//          ."" '<  `.___\_<|>_/___.' >' "".//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |//         \  \ `_.   \_ __\ /__ _/   .-` /  ///     =====`-.____`.___ \_____/___.-`___.-'=====//                   佛祖保佑, 永无bug;}

//-------------------------代码----------------------------
#define int llconst int N = 3000,mod = 1e9+7;int n,m;
int f[N];int tot[N];
void solve(){V<int>v; ms(f,inf);ms(tot,0);string s,t;cin>>s>>t;n = s.size(),m = t.size();s = ' ' + s;v.pb(0);for(int i = 1;i + m - 1 <= n;i ++ ) {if(s.substr(i,m) == t) v.pb(i + m - 1);} f[0] = 0,tot[0] = 1;for(int i = 0;i<v.size();i ++ ) {for(int j = i - 1;j >= 0;j -- ) {if(v[i] - v[j] < m) continue;bool flag = 1;for(int k = j + 1; k < i ;k ++ ) {if(v[k] - v[j] >= m && v[i] - v[k] >= m) {flag = 0;}}if(flag == 0) break;if(f[i] > f[j] + 1) {f[i] = f[j] + 1;tot[i] = tot[j];} else if(f[i] == f[j] + 1) {tot[i] = (tot[i] + tot[j]) % mod;} }}int mi = inf,ans = 0;for(int i = 0; i < v.size();i ++ ) {if(v.back() - v[i] < m) mi = min(mi,f[i]);}for(int i = 0;i < v.size();i ++ ) {if(v.back() - v[i] < m && f[i] == mi) ans = (ans + tot[i]) % mod;} cout<<mi<<' '<<ans<<endl; }void main_init() {}signed main(){AC();clapping();TLE;cout<<fixed<<setprecision(12);main_init();//  while(cin>>n,n)//  while(cin>>n>>m,n,m)int t;cin>>t;while(t -- )solve();//{solve(); }return 0;}
/*样例区

*/
//------------------------------------------------------------



标签:Cut,int,res,Codeforces,tot,flag,size,Round,define
来源: https://www.cnblogs.com/er007/p/16695020.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有