poj3280(區間dp,好題)
給你長度為m的字串,其中有n種字元,每種字元都有兩個值,分別是插入這個字元的代價,刪除這個字元的代價,讓你求將原先給出的那串字元變成一個迴文串的最小代價。
dp[i][j]代表區間i到區間j成為迴文串的最小代價,那麼對於dp[i][j]有三種情況:
1、dp[i+1][j]表示區間i到區間j已經是迴文串了的最小代價,那麼對於s[i]這個字母,我們有兩種操作,刪除與新增,對應有兩種代價,dp[i+1][j]+add[s[i]],dp[i+1][j]+del[s[i]],取這兩種代價的最小值;
2、dp[i][j-1]表示區間i到區間j-1已經是迴文串了的最小代價,那麼對於s[j]這個字母,同樣有兩種操作,dp[i][j-1]+add[s[j]],dp[i][j-1]+del[s[j]],取最小值
3、若是s[i]==s[j],dp[i+1][j-1]表示區間i+1到區間j-1已經是迴文串的最小代價,那麼對於這種情況,我們考慮dp[i][j]與dp[i+1][j-1]的大小........
然後dp[i][j]取上面這些情況的最小值.........//考慮的情況好多
本題總結:
注意資料範圍,m=2000,確定n^2的演算法,兩個迴圈
和最大括號匹配一樣,dp【i】【j】還是表示的i~j這個區間內的狀態,不過這個是二維的,
既然是二維的,且狀態和演算法時間複雜度同階,那麼,dp【i】【j】就一定是從它旁邊的狀態推出來的,而不是列舉以前的狀態,找的
這個題需要考慮的情況不少,狀態轉移方程還是要練,找感覺,這是現在的不足之處,要鍛鍊得
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<string> using namespace std; int n,m,dp[2009][2009],in[27],de[27]; char ch[2009]; int main() { scanf("%d%d",&n,&m); scanf("%s",ch); for (int i=1;i<=n;i++) { char c; if (scanf("%c",&c)&&c=='\n') scanf("%c",&c); int k1,k2; scanf("%d%d",&k1,&k2); in[c-'a']=k1;de[c-'a']=k2; } for (int i=m-1;i>=0;i--) { dp[i][i]=0; for (int j=i+1;j<m;j++) { dp[i][j]=0x3f3f3f3f;//因為找最小的,別忘了開始時置為無窮大 if (ch[i]==ch[j]) dp[i][j]=dp[i+1][j-1]; dp[i][j]=min(dp[i][j],min(dp[i+1][j]+in[ch[i]-'a'],dp[i+1][j]+de[ch[i]-'a'])); dp[i][j]=min(dp[i][j],min(dp[i][j-1]+in[ch[j]-'a'],dp[i][j-1]+de[ch[j]-'a']));//三種情況 //printf("%d %d %d\n",i,j,dp[i][j]); } } printf("%d",dp[0][m-1]); return 0; }
相關推薦
poj3280(區間dp,好題)
給你長度為m的字串,其中有n種字元,每種字元都有兩個值,分別是插入這個字元的代價,刪除這個字元的代價,讓你求將原先給出的那串字元變成一個迴文串的最小代價。 dp[i][j]代表區間i到區間j成為迴文串的最小代價,那麼對於dp[i][j]有三種情況: 1、dp[i+1]
bzoj2287【POJ Challenge】消失之物(dp+補集轉化,好題)
std gree scanf online discus 技術 bsp lin geo 2287: 【POJ Challenge】消失之物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 657 Solved: 382
CodeForces - 793D 區間dp,記憶化
記憶化 ini %d 單向 ble targe set skip ref CodeForces - 793D 題意:一條筆直街道上有標號為 1~n 的 n 個點,有 m 條帶邊權的單向邊。要找一條經過 k 個點的路徑和,限制:每次走過的邊不能跨過已走過的點。 比如點 3
The Doors(幾何+最短路,好題)
The Doors http://poj.org/problem?id=1556 Time Limit: 1000MS Memory Limit: 10000K Total Submis
Escape(狀態壓縮+最大流,好題)
Escape http://acm.hdu.edu.cn/showproblem.php?pid=3605 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (
Marriage Match II(二分+並查集+最大流,好題)
Marriage Match II http://acm.hdu.edu.cn/showproblem.php?pid=3081 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768
【LightOJ - 1031】Easy Game (區間dp,博弈)
題幹: You are playing a two player game. Initially there are n integer numbers in an array and player A and B get chan
Tourism Planning 狀態壓縮DP(好題)
Tourism Planning Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1125 Accepte
E. Bus Video System(找剛開始車上,滿足的人數,好題,細節多)
The busses in Berland are equipped with a video surveillance system. The system records information about changes in the number of passengers in a bus afte
Codeforces Round #312 (Div. 2) (第三題是位運算,好題)
分析:從0座標分開,負半軸一個數組,正半軸一個數組,來記錄果樹的左邊和數量,可以用結構體陣列來儲存資料,其中少的一個半軸上的果樹肯定會全被採光,而多的一邊樹上會多采一棵樹。 struct p{ int num,x; } p neg[105],pos[105];這樣表
Supermarket(並查集,好題)
Supermarket Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11154 Accepted: 4910 Description A supermarket has a set Prod of products on
石子歸併(區間dp的模板題)
石子歸併 題 意:N堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將N堆石子合併成一堆的最小代價。 例如: 1 2 3 4,有不少合併方法 1 2 3 4 => 3 3 4(3) =>
codeforces 878C Tournament平衡樹,好題!!!!
C. Tournament time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output
bzoj1150 堆應用,好題
#include<bits/stdc++.h> using namespace std; #define maxn 100005 #define INF 0x3fffffff #define pa pair<int,int> int n,k,pre[maxn],nxt[maxn
983B XOR-pyramid(區間dp,異或)
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include&l
POJ2955 Brackets(區間DP,括號匹配)
POJ2955 首先考慮怎麼樣定義dp讓它滿足具有通過子結構來求解、 定義dp [ i ] [ j ] 為串中第 i 個到第 j 個括號的最大匹配數目 那麼我們假如知道了 i 到 j 區間的最大匹
51nod 1009 數字1的數量 (統計1的總個數,好題)
給定一個十進位制正整數N,寫下從1開始,到N的所有正數,計算出其中出現所有1的個數。 例如:n = 12,包含了5個1。1,10,12共包含3個1,11包含2個1,總共5個1。 Input 輸入N(1 <= N <= 10^9) Outp
POJ 1191 棋盤分割 (區間DP,記憶化搜索)
bool for ring def bsp sca printf namespace http 題面 思路:分析公式,我們可以發現平均值那一項和我們怎麽分的具體方案無關,影響答案的是每個矩陣的矩陣和的平方,由於數據很小,我們可以預處理出每個矩陣的和的平方,執行狀態轉移。 設
區間DP,子問題的深刻理解
問題描述 有n個矩陣,大小分別為a0*a1, a1*a2, a2*a3, ..., a[n-1]*a[n],現要將它們依次相乘,只能使用結合率,求最少需要多少次運算。 兩個大小分別為p*q和q*r的矩陣相乘時的運算次數計為p*q*r。 輸入格式 輸入的第一行包含一個整數n,表示矩陣的個數
660E Different Subsets For All Tuples (組合數學&DP)好題
考慮dp dp[i][j]表示長度為i,以字元j結尾的答案是多少 dp[i][j]=sigma(dp[i-1][k]*2-dp[pre[j]-1][k]) 然後這個玩意兒顯然對於任意的j的都是一樣的,而且pre[j]前面的每個位置都是可能的,這裡的dp是個字首和,所以直接扣除就可以了 那麼直接化簡為:dp[