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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

bzoj 2121 DP

發(fā)布時間:2025/3/8 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj 2121 DP 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  首先如果我們能處理出來i,j段能不能消掉,這樣就可以直接dp轉(zhuǎn)移了,設w[i]為前i為最少剩下多少,那么w[i]=w[j-1] (flag[j][i])。

  現(xiàn)在我們來求flag[i][j],首先我們可以把字符串組建立trie然后處理在串L中從left位置開始的所有的flag,那么我們可以在trie上一直往下走,每到一個標記的點就將當前的flag[left][right]設為1,那么這樣可以處理出連續(xù)可以消掉的字符串,然后就處理對于類似L為abcde,字符串組為ade,bc這樣可以先消一個,然后再消的情況,這樣我們可以發(fā)現(xiàn),如果對于當前的left,right存在flag[i][right]=1,那么就是這樣的情況,那么我們直接遞歸處理left,i就好了,但是我們發(fā)現(xiàn)這里的flag[i][right]的i是大于left的,所以我們在處理以某個為開頭的所有的flag的時候需要倒序處理。

  有一個優(yōu)化,在同一個left時,我們在處理flag的時候有兩種拓展情況,所以對于每一個i我們記錄一個vis[i][j],表示在當前的left,i節(jié)點,right為j的情況是否訪問過,這樣有訪問的情況return就好了。

  反思:開始沒加優(yōu)化,挺快就a了,后來加了優(yōu)化之后,因為我用的指針存的trie,所以vis數(shù)組中節(jié)點的編號需要對于每個指針都存一個編號,但是這個編號不知道怎么回事兒,一申請就re,后面的按照不加優(yōu)化的寫,只是在node那在cnt之前申請一個num就會re,在cnt之后申請就沒問題,調(diào)了半個上午也不知道怎么回事兒= =,原來一直是這么寫的啊。

  反思2:后來發(fā)現(xiàn)是return的條件為right>=len,寫成right>len了,這樣就有了未定義行為。

/**************************************************************Problem: 2121User: BLADEVILLanguage: C++Result: AcceptedTime:132 msMemory:158900 kb ****************************************************************///By BLADEVIL #include <cstdio> #include <cstring> #include <algorithm> #define maxn 200 #define maxm 1010using namespace std;struct node{int cnt,num; node *child[30];node(){ cnt=num=0;memset(child,0,sizeof child);} }nodepool[maxm],*totnode,*rot;char s[maxn]; int flag[maxn][maxn],vis[maxn][maxm][maxn],w[maxn]; int n,len;void build_trie(){int j=1;totnode=nodepool; rot=totnode++;scanf("%d",&n);char ch[maxn];while (n--) {scanf("%s",ch);int len=strlen(ch);node *t=rot;for (int i=0;i<len;i++) {if (!t->child[ch[i]-'a']) t->child[ch[i]-'a']=totnode++,t->child[ch[i]-'a']->num=j++;t=t->child[ch[i]-'a'];}t->cnt=1;} }void make(node *rot,int left,int right) {//printf("%d ",rot->num);if (rot->cnt) flag[left][right-1]=1;if (vis[left][rot->num][right]) return ;if (right>=len) return ;vis[left][rot->num][right]=1;if (rot->child[s[right]-'a']) make(rot->child[s[right]-'a'],left,right+1);for (int i=right;i<len;i++) if (flag[right][i]) make(rot,left,i+1); }int main() {scanf("%s",s); len=strlen(s);build_trie();for (int i=len-1;i>=0;i--) make(rot,i,i);/*for (int i=0;i<len;i++) {for (int j=0;j<len;j++) printf("%d ",flag[i][j]);printf("\n");}*/w[0]=0;for (int i=0;i<len;i++) {w[i+1]=w[i]+1;for (int j=0;j<=i;j++) if (flag[j][i]) w[i+1]=min(w[i+1],w[j]);//printf("%d ",w[i]); ????}//printf("\n");printf("%d\n",w[len]);return 0; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/BLADEVIL/p/3591127.html

總結(jié)

以上是生活随笔為你收集整理的bzoj 2121 DP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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