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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[OI]字符串DP小结

發布時間:2025/6/17 编程问答 97 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [OI]字符串DP小结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

顧名又思義,是在字符串上進行的DP操作。因為字符串本身可以看作是一個序列,所以有些時候字符串DP可以用區間DP來解決。

P2246 SAC#1 - Hello World(升級版)

題目描述

在講義的某一面,他看見了一篇文章。這篇文章由英文字母(大小寫均有)、數字、和空白字符(制表/空格/回車)構成。

pipapi想起了他最近剛剛學會寫的Hello World程序。他非常好奇,這篇文章中,“HelloWorld”作為子序列到底出現過多少次呢?

由于papapi是個智障,大小寫對于他而言毫無區別;因此,“hEllOWorLD”這樣的子序列也是可以接受的。O和W之間的空格是也是可以少的;也就是說,“HelloWorld”是可以的。根據標程的意思,就是沒有空格,不用考慮空格的情況。

兩個子序列相同當且僅當它們每一個字符所在的位置都相同。

由于答案可能很大,請輸出結果對1000000007(10^9+7)的余數。

輸入輸出格式

輸入格式:

輸入包含若干行。這些行的內容共同構成一篇文章。

文章以EOF(文件結尾)結束。

輸出格式:

輸出僅包含一個整數,表示這篇文章中“Hello World”出現的次數。 d

輸入輸出樣例

輸入樣例#1:

HhEeLlLlOoWwOoRrLlDd

輸出樣例#1:

1536

輸入樣例#2:

Gou Li Guo Jia Sheng Si Yi Qi Yin Huo Fu Bi Qu Zhi River can feed people Also can race boats Hall Ellen Ok Words locked

輸出樣例#2:

273

說明

記n為輸入的文章的長度(字符數)。

對于20%的數據,n <= 20。

對于50%的數據,n <= 500。

對于所有的數據,15 <= n <= 500000。

入門題。設\(dp[i][j]\)表示文本串前i個字符匹配helloworld模板的前j個字符的匹配數。顯然當\(a[i]=b[j]\)時有\(dp[i][j]=dp[i-1][j-1] + dp[i-1][j]\),其他情況\(dp[i][j]=dp[i-1][j]\)。前面一維直接滾動優化掉。

#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std;typedef long long LL; const int MOD = 1e9 + 7; char ch1[233] = "#helloworld"; char ch2[233] = "#HELLOWORLD"; int f[233];int main() {char x; f[0] = 1;while ((x = getchar())!=EOF) for (int i = 10; i >= 1; -- i) if (x == ch1[i] || x == ch2[i]) f[i] = (f[i-1] + f[i]) % MOD;cout << f[10] << endl;return 0; }

P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome

題目描述

Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow an electronic ID tag that the system will read as the cows pass by a scanner. Each ID tag's contents are currently a single string with length M (1 ≤ M ≤ 2,000) characters drawn from an alphabet of N (1 ≤ N ≤ 26) different symbols (namely, the lower-case roman alphabet).

Cows, being the mischievous creatures they are, sometimes try to spoof the system by walking backwards. While a cow whose ID is "abcba" would read the same no matter which direction the she walks, a cow with the ID "abcb" can potentially register as two different IDs ("abcb" and "bcba").

FJ would like to change the cows's ID tags so they read the same no matter which direction the cow walks by. For example, "abcb" can be changed by adding "a" at the end to form "abcba" so that the ID is palindromic (reads the same forwards and backwards). Some other ways to change the ID to be palindromic are include adding the three letters "bcb" to the begining to yield the ID "bcbabcb" or removing the letter "a" to yield the ID "bcb". One can add or remove characters at any location in the string yielding a string longer or shorter than the original string.

Unfortunately as the ID tags are electronic, each character insertion or deletion has a cost (0 ≤ cost ≤ 10,000) which varies depending on exactly which character value to be added or deleted. Given the content of a cow's ID tag and the cost of inserting or deleting each of the alphabet's characters, find the minimum cost to change the ID tag so it satisfies FJ's requirements. An empty ID tag is considered to satisfy the requirements of reading the same forward and backward. Only letters with associated costs can be added to a string.

字串S長M,由N個小寫字母構成。欲通過增刪字母將其變為回文串,增刪特定字母花費不同,求最小花費。

輸入輸出格式

輸入格式:

Line 1: Two space-separated integers: N and M

Line 2: This line contains exactly M characters which constitute the initial ID string

Lines 3..N+2: Each line contains three space-separated entities: a character of the input alphabet and two integers which are respectively the cost of adding and deleting that character.

輸出格式:

Line 1: A single line with a single integer that is the minimum cost to change the given name tag.

輸入輸出樣例

輸入樣例#1:

3 4 abcb a 1000 1100 b 350 700 c 200 800

輸出樣例#1:

900

說明

If we insert an "a" on the end to get "abcba", the cost would be 1000. If we delete the "a" on the beginning to get "bcb", the cost would be 1100. If we insert "bcb" at the begining of the string, the cost would be 350 + 200 + 350 = 900, which is the minimum.

比較經典的字符串DP了。設\(dp[i][j]\)表示區間[i,j]變成回文串的最小花費,需要用到區間DP的思想。考慮如何用一個小區間更新一個大區間。如果大區間是\(dp[i][j]\),若s[i]=s[j],那么\(dp[i][j]=dp[i+1][j-1]\),即當前大區間可以由去掉其兩端的小區間更新而來而不用花費。不等的時候,\(dp[i][j]=min(dp[i+1][j]+min(add[s[i]],del[s[i]]),dp[i][j-1]+min(add[s[j],del[s[j]]])\)

#include<iostream> #include<algorithm> using namespace std;const int M = 2005, N = 256; int n, m; char c, s[M]; int del[N], add[N], f[M][M];int main() {scanf("%d%d%s", &n, &m, (s+1));for (int i = 1; i <= n; ++ i) {cin >> c; cin >> add[c] >> del[c];} for (int L = 2; L <= m; ++ L) for (int i = 1; i + L - 1 <= m; ++ i) {int j = i + L - 1;if (s[i] == s[j]) f[i][j] = f[i + 1][j - 1];else f[i][j] = min(f[i+1][j] + min(add[s[i]], del[s[i]]),f[i][j-1] + min(add[s[j]], del[s[j]]));}cout<<f[1][m]<<endl;return 0; }

P1279 字串距離

題目描述

設有字符串X,我們稱在X的頭尾及中間插入任意多個空格后構成的新字符串為X的擴展串,如字符串X為”abcbcd”,則字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的擴展串,這里“□”代表空格字符。

如果A1是字符串A的擴展串,B1是字符串B的擴展串,A1與B1具有相同的長度,那么我捫定義字符串A1與B1的距離為相應位置上的字符的距離總和,而兩個非空格字符的距離定義為它們的ASCII碼的差的絕對值,而空格字符與其他任意字符之間的距離為已知的定值K,空格字符與空格字符的距離為0。在字符串A、B的所有擴展串中,必定存在兩個等長的擴展串A1、B1,使得A1與B1之間的距離達到最小,我們將這一距離定義為字符串A、B的距離。

請你寫一個程序,求出字符串A、B的距離。

輸入輸出格式

輸入格式:

輸入文件第一行為字符串A,第二行為字符串B。A、B均由小寫字母組成且長度均不超過2000。第三行為一個整數K(1≤K≤100),表示空格與其他字符的距離。

輸出格式:

輸出文件僅一行包含一個整數,表示所求得字符串A、B的距離。

輸入輸出樣例

輸入樣例#1

cmc snmn 2

輸出樣例#1:

10

\(dp[i][j]\)表示第一個串的前i個字符和第二個串的前j個字符的最優值,兩個空格對應顯然沒有意義,那么有3種轉移:\(dp[i-1][j]+K\)\(dp[i][j-1]+K\)\(dp[i-1][j-1]+abs(S1[i]-S2[j])\),分別表示S1[i]與空格匹配,S2[j]與空格匹配,S1[i]與S2[j]匹配。

#include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <cctype> #include <map> #include <queue> #include <vector> #include <iostream> #include <algorithm> using namespace std;const int MAXN = 2010; int K; char S1[MAXN], S2[MAXN]; int dp[MAXN][MAXN];int clac(int i, int j) {return abs((int) (S1[i] - 'a') - (int) (S2[j] - 'a')); }int main( ) {scanf("%s%s%d", S1 + 1, S2 + 1, &K);int len1 = strlen(S1 + 1), len2 = strlen(S2 + 1); memset(dp, 63, sizeof(dp));dp[0][0] = 0;for (int i = 0; i <= len1; ++ i)for (int j = 0; j <= len2; ++ j) {if (i) dp[i][j] = min(dp[i][j], dp[i - 1][j] + K);if (j) dp[i][j] = min(dp[i][j], dp[i][j - 1] + K);if (i && j) dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + clac(i, j));}printf("%d\n", dp[len1][len2]);return 0; }

caioj 1061: [視頻]背包7(匹配性填滿型 完全 背包)

時間限制: 1 Sec 內存限制: 128 MB

【問題描述】
判斷句子是否可以被劃分成若干單詞,這些單詞只可以 “one”、“puton”、“out”、“output”、“in”和“input”。
輸入n個字符串,長度不超過1000000,表示一句句子。
如果可能是那兩個人的對話,則輸出“YES”;否則,輸出“NO”。
【輸入文件】
第一行一個整數n,表示一共有n句句子。
此后每行一個字符串,表示一句句子。
【輸出文件】
n行,每行一個“YES”或“NO”,表示你的判斷結果。

樣例輸入輸出

樣例輸入

6 puton inonputin oneputonininputoutoutput oneininputwooutoutput outpu utput

樣例輸出

YES NO YES NO NO NO

如果不知道這是一道背包題的話,可能沒幾個人會往背包的方面想。我們不妨把題目中給定的6個單詞看做六個數量無限的物品,現在他們要裝到一個背包中,比如要裝一個input,能裝入背包的條件是當前裝了一些的背包中,再往后需要的字母依次是i,n,p,u,t。最后成功的條件是背包被裝滿,即\(dp[串長]\)有值。\(dp[i]\)表示前i個字符是否能完成匹配。如上所述,則dp[i]能由dp[i - len[i]] 推出,當且僅當,子串c[j - len[i] ~ j] 為給定的單詞。

單純這樣做還會TLE??梢院唵蝺灮幌?#xff0c;具體參照代碼。

#include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <cctype> #include <map> #include <queue> #include <vector> #include <iostream> #include <algorithm> using namespace std;const int MAXM = 1000010; const int MAXN = 1010; int n; string c[] = {"", "one", "puton", "out", "output", "in", "input"}; int len[] = {0, 3, 5, 3, 6, 2, 5}; int dp[MAXM];int main( ) {scanf("%d", &n);string s; int l;for (int i = 1; i <= n; ++ i) {memset(dp, 0, sizeof(dp));cin >> s; l = s.size( );dp[0] = 1;for (int j = 1; j <= l; ++ j)if(s[j - 1] == 'e' || s[j - 1] == 'n' || s[j - 1] == 't') //優化for (int i = 1; i <= 6; ++ i) if (j - len[i] >= 0) if(s[j - len[i]] == 'o' || s[j - len[i]] == 'p' || s[j - len[i]] == 'i') //優化if (s.substr(j - len[i], len[i]) == c[i])dp[j] = dp[j] | dp[j - len[i]];if (dp[l]) printf("YES\n");else printf("NO\n");} }

P1136 迎接儀式

題目描述

LHX教主要來X市指導OI學習工作了。為了迎接教主,在一條道路旁,一群Orz教主er穿著文化衫站在道路兩旁迎接教主,每件文化衫上都印著大字。一旁的Orzer依次擺出“歡迎歡迎歡迎歡迎……”的大字,但是領隊突然發現,另一旁穿著“教”和“主”字文化衫的Orzer卻不太和諧。

為了簡單描述這個不和諧的隊列,我們用“j”替代“教”,“z”替代“主”。而一個“j”與“z”組成的序列則可以描述當前的隊列。為了讓教主看得盡量舒服,你必須調整隊列,使得“jz”子串盡量多。每次調整你可以交換任意位置上的兩個人,也就是序列中任意位置上的兩個字母。而因為教主馬上就來了,時間僅夠最多作K次調整(當然可以調整不滿K次),所以這個問題交給了你。

輸入輸出格式

輸入格式:

第一行包含2個正整數N與K,表示了序列長度與最多交換次數。

第二行包含了一個長度為N的字符串,字符串僅由字母“j”與字母“z”組成,描述了這個序列。

輸出格式:

一個非負整數,為調整最多K次后最后最多能出現多少個“jz”子串。

輸入輸出樣例

輸入樣例#1:

5 2 zzzjj

輸出樣例#1:

2

說明

【樣例說明】

第1次交換位置1上的z和位置4上的j,變為jzzzj;

第2次交換位置4上的z和位置5上的j,變為jzzjz。

最后的串有2個“jz”子串。

【數據規模與約定】

對于10%的數據,有N≤10;

對于30%的數據,有K≤10;

對于40%的數據,有N≤50;

對于100%的數據,有N≤500,K≤100。

一開始不知道怎么做。考慮\(dp[i][j][k]\)表示考慮前i個字符,有j個j變成了z,k個z變成了j。

然后呢?

然后我就不知道了

首先顯然兩個一樣的字符不會被修改。

相鄰兩字符有四種情況可以轉移:zj jz jj zz。

\(s[i]='j' ~\&\&~ s[i-1]='z'\)\(dp[i][j][k]=max(dp[i][j][k],dp[i-2][j][k]+1);\)

\(s[i]='z' ~\&\&~ s[i-1]='j'\)\(dp[i][j][k]=max(dp[i][j][k],dp[i-2][j-1][k-1]+1);\)

上面兩種情況都比較顯然。

那么另外兩種情況呢?

\(s[i]='j' ~\&\&~ s[i-1]='j'\)\(dp[i][j][k]=max(dp[i][j][k],dp[i-2][j-1][k]+1);\)

\(s[i]='z' ~\&\&~ s[i-1]='z'\)\(dp[i][j][k]=max(dp[i][j][k],dp[i-2][j][k-1]+1);\)

感性理解一下就是,我把不合法的變成合法的,可以看做當前不合法的與前面或后面某個數交換了一下,使之合法,但具體是與哪個數交換的,我們不需要去知道。因為當交換次數\(j=k\)時,顯然是存在至少一種合法的操作順序,令原字符串可以通過j=k次交換變成合法。當交換次數\(j \not= k\)時,顯然不存在這種交換方式,那我們就不必去管他。

最后對所有的\(dp[N][i][i]\)取max。

比較巧妙。

順便,注意邊界處理。

#include <algorithm> #include <cctype> #include <cmath> #include <cstring> #include <cstdlib> #include <cstdio> #include <ctime> #include <iostream> #include <map> #include <queue> #include <vector> using namespace std;const int INF = 0x3f3f3f3f; const int MAXN = 510; const int MAXK = 110; int N, K; //dp[i][j][k]表示考慮前i個字符,有j個‘j’變成了z,k個‘z’變成了j int l[MAXN], dp[MAXN][MAXK][MAXK]; char tmp[MAXN];template <typename _Tp> inline void read(_Tp &x) {char ch = getchar( ); bool f = 0; x = 0;while (!isdigit(ch)) { if (ch == '-') f = 1; ch = getchar( ); }while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar( );x = f ? -x : x; }int main( ) {memset(dp, ~63, sizeof(dp));read(N), read(K);scanf("%s", tmp + 1);for (int i = 1; i <= N; ++ i) if (tmp[i] == 'z') l[i] = 1;else l[i] = 0;//for (int i = 1; i <= N; ++ i) printf("%d\n", l[i]);dp[0][0][0] = dp[1][0][0] = dp[1][l[1]][l[1]] = 0;for (int i = 2; i <= N; ++ i) for (int j = 0; j <= K; ++ j)for (int k = 0; k <= K; ++ k) {dp[i][j][k] = dp[i - 1][j][k];if (!l[i - 1] && l[i]) dp[i][j][k] = max(dp[i][j][k], dp[i - 2][j][k] + 1);if (k && l[i] && l[i - 1])dp[i][j][k] = max(dp[i][j][k], dp[i - 2][j][k - 1] + 1);if (j && !l[i] && !l[i - 1])dp[i][j][k] = max(dp[i][j][k], dp[i - 2][j - 1][k] + 1);if (j && k && !l[i] && l[i - 1]) dp[i][j][k] = max(dp[i][j][k], dp[i - 2][j - 1][k - 1] + 1);}int ans = 0;for (int i = 0; i <= K; ++ i) ans = max(ans, dp[N][i][i]);printf("%d\n", ans);return 0; }

轉載于:https://www.cnblogs.com/hkttg/p/10162391.html

總結

以上是生活随笔為你收集整理的[OI]字符串DP小结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩欧美一区二区在线观看 | 欧美混交群体交 | 久久爱影视i| 澳门免费av | 日日日干 | 欧美精品 在线观看 | 五月天综合色 | 丁香花完整视频在线观看 | 国产欧美日韩高清 | 亚洲一区中文字幕在线 | 成人免费在线观看 | 打屁屁日本xxxxx变态 | 奇米影视大全 | 高清免费av | 4438x在线观看 | 亚洲v欧美v| 尤物网站在线观看 | 午夜毛片在线观看 | 日韩精品h | 精品成人 | 不卡中文字幕 | aaaa级片| 国产精品成人99一区无码 | 久久久久久久人妻无码中文字幕爆 | 国产精品一区二区免费在线观看 | a天堂在线观看 | 亚洲午夜精品一区二区三区 | 国产一区二区免费在线 | 中文资源在线观看 | 国产精品视频在线看 | 日本成人免费在线视频 | 中文在线天堂网 | 手机看片一区 | 一级全黄少妇性色生活片 | 成年人免费在线观看网站 | 国产精品久久久久毛片大屁完整版 | 精品国产乱码久久久久久图片 | 日韩第一页在线观看 | 美女扒开内裤让男人桶 | 伊人激情在线 | 五月婷婷免费视频 | 欧美在线视频免费观看 | 欧美日韩精品在线视频 | 狼人综合av | 国产性猛交╳xxx乱大交 | 男女性杂交内射妇女bbwxz | 欧美一区二区三区在线免费观看 | 成人在线日韩 | 亚洲自拍网站 | 狠狠干av | 亚洲精品久久久久久久久久久久久 | 免费的黄色网址 | 久久久在线视频 | 亚洲aⅴ | 国产精品久久久久久久久动漫 | 精品国产乱码久久久久久久软件 | 在线观看av不卡 | 亚洲精品国产成人无码 | 久操香蕉 | 夜夜嗨av禁果av粉嫩avhd | 中国男人操女人 | 国产一区,二区 | 婷婷免费视频 | 在线观看免费视频 | 国产成人a亚洲精品 | 国产色在线 | 免费在线看黄网址 | 欧美日韩精品一区二区三区蜜桃 | 亚洲AV无码国产成人久久 | 美女无遮挡免费网站 | 蜜桃久久久久久 | 日韩av在线一区二区三区 | 久久久久久免费毛片精品 | 亚洲一区黄色 | 欧美经典一区二区 | 精品一区av | 精品国产鲁一鲁一区二区三区 | 亚洲成人久久久 | 午夜免费播放观看在线视频 | 91中文字幕在线 | 操啊操 | 毛片免费全部无码播放 | 都市激情亚洲色图 | 亚洲一区二区三区影视 | 亚洲精品一区二区三区四区乱码 | www.97av| 麻豆剧场| 久草在| 国产人成在线 | 无码精品一区二区三区在线 | 乱人伦xxxx国语对白 | 亚洲成人精品视频 | 国产精品羞羞答答 | 国产亚洲女人久久久久毛片 | aa黄色片| 欧美人与禽猛交乱配视频 | 亚洲综合视频一区 | 女人和拘做爰正片视频 | 毛片视频观看 |