日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

操作集锦【牛客网】 牛客练习赛60

發(fā)布時(shí)間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作集锦【牛客网】 牛客练习赛60 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目傳送

時(shí)間限制:C/C++ 1秒,其他語(yǔ)言2秒 空間限制:C/C++ 262144K,其他語(yǔ)言524288K 64bit IO Format:
%lld

題目描述

有一款自走棋有26種操作,每種操作我們都用a,b,c,d,…,x,y,z的符號(hào)來(lái)代替.
現(xiàn)在牛牛有一個(gè)長(zhǎng)度為nnn的操作序列,他現(xiàn)在可以從里面拿出某些操作來(lái)組合成一個(gè)操作視頻,
比如說(shuō)操作序列是abcdabcdabcd,那么操作視頻就有a,b,c,d,ab,ac,ad等(也就是操作序列的子序列).他現(xiàn)在想知道長(zhǎng)度為k且本質(zhì)不同的操作視頻有多少種.
比如對(duì)于abab,長(zhǎng)度為2且本質(zhì)不同的結(jié)果有ab,aa,ba,bb 考慮到答案可能非常大,你只需要輸出在模1e9+7意義下的答案就可以了.

輸入描述:

第一行兩個(gè)整數(shù)n,k 第二行一個(gè)長(zhǎng)度為n的字符串,保證只存在小寫(xiě)字母.

輸出描述:

一行一個(gè)整數(shù)表示長(zhǎng)度為k且本質(zhì)不同的操作視頻的個(gè)數(shù).

示例1
輸入

3 1 abc

輸出

3

備注:

1≤n≤1e3
0≤k≤n
題意
給你一個(gè)長(zhǎng)度為n的字符串,問(wèn)有多有長(zhǎng)度為k的子字符串,且不重復(fù)。
題解:
這種求子字符串?dāng)?shù)量題一般都用dp來(lái)做
dp[i][j]表示q前i個(gè)字符串中,長(zhǎng)度為j的子字符串的數(shù)量
但是這個(gè)題是存在重復(fù)情況的,我們還要進(jìn)行去重
這咋整?我們將dp從二維增加到三維,dp[i][j][k]新填一個(gè)k,k表示以什么字母結(jié)尾,(因?yàn)槲覀兛梢詫~z轉(zhuǎn)換成數(shù)字,a對(duì)應(yīng)0,b對(duì)應(yīng)1,一次類推),在dp添加時(shí)我們if判斷,如果當(dāng)前結(jié)尾不是我們指定的字母,就不添加當(dāng)前這位;如果是的話,就在前面的基礎(chǔ)在最后一位填上這個(gè)字母。
不明白?很正常(笑哭),我也快把自己講暈了
這個(gè)k就相當(dāng)于是針對(duì)性的,dp[i][j][k]就是前i個(gè)字符串中選j個(gè)以k為結(jié)尾的字符數(shù)量
舉例大法:n=4 m=2
abab

你會(huì)發(fā)現(xiàn)鏈接對(duì)于abab,長(zhǎng)度為2且本質(zhì)不同的結(jié)果有ab,aa,ba,bb,雖然abab的子字符串中ab出現(xiàn)兩次,但是只統(tǒng)計(jì)了一次,因?yàn)樵谒阋詁(最后這個(gè)b)為結(jié)尾的時(shí)候,前面兩個(gè)a算作一個(gè)a處理
代碼:

#include<bits/stdc++.h> using namespace std; const int maxn=1004; int dp[maxn][maxn][30]; char a[maxn]; const int mod=1e9+7; long long sum=0; int main() {int n,m;cin>>n>>m;char ch=getchar();cin>>a;if(m==0){cout<<1;return 0;}for(int i=1;i<=n;i++){dp[i][1][a[i-1]-'a']=1;for(int j=1;j<=m;j++){for(int w=0;w<=25;w++){if(a[i-1]-'a'==w){for(int k=0;k<=25;k++){dp[i][j][w]=(dp[i][j][w]+dp[i-1][j-1][k])%mod;}}else dp[i][j][w]=(dp[i][j][w]+dp[i-1][j][w])%mod;}}}for(int i=0;i<=25;i++)sum=(sum+dp[n][m][i])%mod;cout<<sum; }

**注意注意:**不要忘了MOD
據(jù)說(shuō)還能優(yōu)化,等學(xué)會(huì)了再更新

啦啦啦我又回來(lái)了

上面這個(gè)解法復(fù)雜度是O(26n2)
我們這次把26給省掉變成O(n2
設(shè)兩個(gè)數(shù)組
g[i]:在前i個(gè)字符長(zhǎng)度為j的本質(zhì)不同的子序列個(gè)數(shù)
f[i][j]:前i個(gè)字符長(zhǎng)度為j的本質(zhì)不同的子序列個(gè)數(shù)
f[i][j]=f[i-1][j-1]+f[i-1][j]
f[i-1][j-1]就是不選擇s[i]
f[i-1][j]就是選擇s[i]
選擇的s[i]加上后有可能會(huì)重復(fù),就需要我們先判斷當(dāng)前的s[i]是否用過(guò),然后把重復(fù)的部分去掉
f [ i ] [ j ] =f[ i ] [ j ]-f[ g [ s [ i ] ] - 1 ] [ j - 1 ]
還有在加的過(guò)程中注意不斷的mod

#include <bits/stdc++.h> using namespace std; #define LL long long const int mod=1e9+7;char s[100005]; LL f[1005][1005], g[30]={0}; int main() {int n, k;scanf("%d%d", &n, &k);scanf("%s", s+1);for(int i=1; i<=n; i++){f[i-1][0]=1;for(int j=1; j<=i; j++){f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;if(g[s[i]]){f[i][j]-=f[g[s[i]]-1][j-1];}f[i][j]=(f[i][j]+mod)%mod;}g[s[i]]=i;}f[n][0]=1;cout<<f[n][k]%mod<<endl;return 0; }

總結(jié)

以上是生活随笔為你收集整理的操作集锦【牛客网】 牛客练习赛60的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。