標籤(空格分隔): 區間dp 回文詞
追蹤每頭奶牛的去向是一件棘手的任務,為此農夫約翰安裝了一套自動系統。他在每頭牛身上安裝了乙個電子身份標籤,當奶牛通過掃瞄器的時候,系統可以讀取奶牛的身份資訊。目前,每個身份都是由乙個字串組成的,長度為m (1≤m≤2000),所有的字元都取自小寫的羅馬字母。
奶牛們都是頑皮的動物,有時她們會在通過掃瞄器的時候倒著走,這樣乙個原來身份為abcb的奶牛就可能有兩個不同的身份了(abcb和bcba),而如果身份是abcba的話就不會有這個問題了。
約翰想改變奶牛們的身份,使他們不管怎麼走讀起來都一樣。比如說,abcb可以在最後加個a,變成回文abcba;也可以在前面加上bcb,變成回文bcbabcb;或者去除字母a,保留的bcb也是一條回文。總之,約翰可以在任意位置刪除或插入一些字元使原字串變成回文。
不巧的是,身份標籤是電子做的,每增加或刪除乙個字母都要付出相應的費用(0≤代價≤10000)。給定一頭奶牛的身份標籤和增加或刪除相關字母的費用,找出把原來字串變成回文的最小費用。注意空字串也是回文。
輸入格式
第一行:兩個用空格分開的整數:n和m 第二行:乙個長度恰好為m的字串,代表初始的身份標籤 第三行到第n+2行:每行為乙個用空格分開的三元組:其中包括乙個字元和兩個整數,分別表示增加或刪除這個字元的費用
輸出格式
第一行:只有乙個整數,表示改造這個身份標籤的最小費用
樣例樣例輸入
3 4abcb
a 1000 1100
b 350 700
c 200 800
樣例輸出
900資料範圍與提示
如果在最後插入乙個a,得到abcba,代價為1000;如果刪除第乙個a,得到bcb,代價為1100;如果在字串的開頭插入bcb,代價為350+200+350=900,這才是最優的做法
這道題很噁心,不愧是學校題庫的最後一題。線型dp和區間dp都是以回文詞結尾,但是這兩道思路完全不同,難度可想而知。
對於一塊新區間,要想保證區間中的元素是回文詞,那就必須保證首元素和尾元素相同。如果相同,那麼f[i][j]就能直接從f[i-1][j-1]轉移過來,而且不用代價。如果不同,我們可以只處理首元素和尾元素中的乙個。處理首元素,我們可以從f[i+1][j]轉移過來,然後要麼刪除首元素,要麼在尾端插入乙個首元素。處理尾元素,我們可以從f[i][j-1]轉移過來,同前。
#include#include#include#include#includeusing namespace std;
const int maxn=2e5+5,inf=0x3f3f3f3f,maxe=2e3+5;
int n,m,f[maxe][maxe],low[maxn],ans,del[maxn],add[maxn];
inline int read()
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}int main()//還是我沒用快讀時寫的
memset(f,0x3f,sizeof(f));
for(int i=0;i<=n+1;i++)f[i][i]=0;//初始化
for(int d=2;d<=n;d++)
else f[i][j]=min(f[i+1][j]+min(del[a[i]],add[a[i]]),f[i][j-1]+min(del[a[j]],add[a[j]]));//不相等,要麼在對a[i]刪除或插入,要麼對a[j]刪除或插入
} }cout《嚶嚶嚶 嚶嚶嚶 嚶嚶嚶嚶嚶
低價回文 區間dp
題目描述 追蹤每頭奶牛的去向是一件棘手的任務,為此農夫約翰安裝了一套自動系統。他在每頭牛身上安裝了乙個電子身份標籤,當奶牛通過掃瞄器的時候,系統可以讀取奶牛的身份資訊。目前,每個身份都是由乙個字串組成的,長度為m 1 m 2000 所有的字元都取自小寫的羅馬字母。奶牛們都是頑皮的動物,有時她們會在通...
最長回文子串(區間dp)
輸入乙個字串str,輸出str裡最長回文子串的長度。回文串 指aba abba cccbccc aaaa這種左右對稱的字串。串的子串 乙個串的子串指此 字元 串中連續的一部分字元構成的子 字元 串 例如 abc 這個串的子串 空串 a b c ab bc abc 輸入str str的長度 1000 ...
牛牛的回文串(區間dp)
第一行輸入乙個字串s 都是小寫字母 表示牛妹給牛牛的串 1 s 50 第二行輸入乙個整數m 0 m 50 接下來m行的格式是 add c x erase c x change c1 c2 x 三種中的一種 c c1 c2都是小寫字母 1 x 100000 所有允許的操作去除x部分後都是不同的輸出乙個...