區(qū)間dp錯題
·https://www.luogu.com.cn/problem/P4170
“出師未捷身先死”的思路:既然是l到r能刷成一種,不難想到區(qū)間,接著又是最小方案數(shù),可能是區(qū)間dp,那肯定有[l][r],表示【l,r】中變成指定字符串的最小方案量,但是怎么知道上一次把這個區(qū)間的字符串都刷成什么了呢?(有這個疑問的原因是既然我要在修改的基礎上再次修改,我就得知道上次刷成什么樣了,也就是這次我得到的字符串是長什么樣子)所以再加一個維度color,表示這個區(qū)間里字符串都刷成什么了,然后進行修改,具體代碼如下
#include<bits/stdc++.h>
using namespace std;
const int maxn=numeric_limits<int>::max();
string s;
int dp[51][51][26];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s;
int n=s.size();
for(int i=0;i<n;i++)
{
for(int j=0;j<26;j++)
{
if(s[i]-'A'==j)
{
continue;
}
dp[i][i][j]=1;
}
}
for(int i=0;i+1<n;i++)
{
for(int j=0;j<26;j++)
{
if(s[i]==s[j])
{
if(s[i]-'A'!=j)
dp[i][i+1][j]=1;
}
else
{
if(s[i]-'A'==j)
{
dp[i][i+1][j]=1;
}
else if(s[i+1]-'A'==j)
{
dp[i][i+1][j]=1;
}
else
dp[i][i][j]=2;
}
}
}
for(int l=n-3;l>=0;l--)
{
for(int r=l+2;r<n;r++)
{
for(int color=0;color<26;color++)
{
if(s[l]=='A'+color && s[r]=='A'+color)
dp[l][r][color]=dp[l+1][r-1][color];
else if(s[l]=='A'+color)
dp[l][r][color]=dp[l+1][r][color];
else if(s[r]=='A'+color)
dp[l][r][color]=dp[l][r-1][color];
else
{
int start=-1,ans=0;
for(int i=l;i<=r;i++)
{
if(s[i]=='A'+color)
{
if(start!=-1)
{
dp[l][r][color]+=dp[start][i-1][s[start]-'A']+1;
start=-1;
}
continue;
}
if(start==-1)
start=i;
}
if(start!=-1)
dp[l][r][color]+=dp[start][r][s[start]-'A']+1;
}
}
}
}
cout<<dp[0][n-1][s[0]-'A']+1;
return 0;
}
這個會WA,只能得40分
正確思路引導:誠如錯誤思路所言,肯定有[l][r],表示【l,r】中變成指定字符串的最小方案量,這里抓住題目的特殊點——一個區(qū)間全部刷成某個字符,這個有什么用?聯(lián)系可能性的試法,兩端點。那么意味著如果兩個端點相同,開頭可以帶著結尾刷,結尾不用再考慮(也可以是結尾帶著開頭刷,情況一樣),因此就有方程轉移,if(s[l]==s[r]) dp[l][r]=dp[l][r-1] (也可以是=dp[l+1][r])。誒,為什么不能是dp[l+1][r-1]+1呢?從樣例一中可以發(fā)現(xiàn)AAAAA的時候,會多算,因此不行。ok,現(xiàn)在看當不相等的時候會是什么情況,既然不相等就沒得帶了,所以個人管個人的,就是枚舉分界點就行,這里注意分界點范圍[l,r),不能等于r,額哈哈當時一直檢查沒檢查出來
·https://www.luogu.com.cn/problem/P3205
“出師未捷身先死”的思路:這邊想著n<=1000不能暴力,意味著不能枚舉,只能抽象化算,最近被這種要抽象化吊打久了條件反射要用dp,首先背包和數(shù)位可能性比較小,但是區(qū)間好像有點看不出來怎么回事。我一直認為dp講究的是個可能性嘗試,所以我就去找這個規(guī)律,我發(fā)現(xiàn),如果是l在最后面,那么它依靠的就是[l+1,r],r的情況同樣適用,想到這里我就和正確思路開始有偏差了:那又不是[l+1,r]的所有情況,萬一nums[l]最后組成的數(shù)怎么辦?最后組成的數(shù)又不知道(這里犯了個錯誤,我在想記錄下來最后一個數(shù),但是很顯然這會重復我也想到了。后來就沒繼續(xù)思路了。我認為原因是這邊思路已經(jīng)偏具體化,遠離了dp設計,而且忘記了dp的每個狀態(tài)似乎都是同一模式下求解,像分治),而且萬一l是開頭最先出的數(shù)怎么辦?(這邊似乎忘了r為最后出現(xiàn)的時候應考慮了)哈哈,結果顯而易見,思路崩盤
正確思路引導:既然是“出師未捷身先死”的思路,自然有它的可取之處,只要稍微引導一下即可。首先,延續(xù)它的可能性落腳點,如果是l最后出現(xiàn),那么我們考慮在[l+1,r]的范圍上最后一個出現(xiàn)的數(shù)與l的關系進行討論即可,然后還有r作為最后出現(xiàn)的情況。那么會發(fā)現(xiàn)有兩種情況,這時候就要添加另一個維度了,表示是頭部最后出現(xiàn)還是尾部最后出現(xiàn)
Leetcode546. 移除盒子
“出師未捷身先死”的思路:這道題首先問的是最大值,想到dp和二分,二分不行于是目光轉向dp,觀察樣例和特殊條件竟然是消除數(shù)的題目那應該可以想到區(qū)間dp。觀察樣例,這個似乎只用l,r無法遞推,因為有一些相同的是刪除了中間的再拼起來的,或者是不拼。那么這時候應該可以想到記錄前綴信息。這里我記錄的是前面有k個與l-1相同的顏色,與l不相同。然后討論可能性,這里經(jīng)過一系列對自己的質疑終究沒有討論出來(⊙o⊙)…。咳咳,先看問題所在,這里我想的是在【l,r】中找一個與l-1相同的數(shù),然后看看后面有沒有連著的與之相同的數(shù),進行合并計算答案。這個其實就是正確引導思路,但是后面進行天馬行空式雜糅后就出現(xiàn)了
2,2,2……2,2……,2,2 這個前面有多少個2我要記錄嘛?不要,因為會雜糅,當我將k和第一個段2進行合并時后面的情況其實都考慮到了,如果加起來的話就考慮不到不要第一個段2的情況
正確思路引導:在上面的思路基礎上把那個錯誤點刪除即可
Leetcode1000. 合并石頭的最低成本
“出師未捷身先死”的思路:觀察發(fā)現(xiàn),每次消耗的都是(k-1)個,所以%一下(k-1)就能判斷是否可以分出來。但是最后一個是必須是k,所以公式為(n-1)%(k-1)。這邊遞推方程出了問題,總的來說是因為設置最大值后相加才會出現(xiàn)問題

正確思路引導:其實那個思路沒有問題,但是需要再進行整理,為了避免加到最大值,dp要全設置為0,所以不能直接給dp[l][r]賦值,而是要設置一個變量ans。ok,現(xiàn)在觀察,發(fā)現(xiàn)無論可不可以組成一堆,他們最終組成的堆數(shù)都是不變的,設置為q。分析可能性,1)可以組成一堆 則要分成 1和k-1堆 這時候枚舉1堆的邊界點即可,為+=k-1 2)分成p堆(p!=1)則要分成p和p-1堆,同1)
Leetcode730. 統(tǒng)計不同回文子序列
“出師未捷身先死”的思路:兩端點的考慮,然后,然后就時間到了(其實是漏看題目信息最后不了了之)
正確思路引導:考慮兩個端點
1)s[l]==s[r] 2)s[l]!=s[r]
a.l-1到r-1中沒有s[l] (dp[l+1][r-1]<<1)+2 dp[l][r-1]+dp[l+1][r]-dp[l+1][r-1]+mod
b.l-1到r-1中有1個s[l] (dp[l+1][r-1]<<1)+1
c.l-1到r-1中有多個sl-dp[i+1][j-1]+mod
后邊用容斥原理或舉例子即可 這里的i指的是離l最近的右邊的s[l],j是離r最近的左邊的s[l]
綜上所述(今天似乎都是出師未捷身先死QAQ)
1.dp是抽象化的,考慮可能性時要抽象->具體->抽象,即題意->用例子規(guī)律和題目的特殊性質分心可能性落腳點->轉移的時候注意抽象化轉移,第一道和第二道都在想記錄上一個是什么,但這樣不僅累贅而且可能會算重
2.思路錯了就退一步,不要完全放棄,也不要拼命死磕,因為你以為的錯誤思路或許是正解的雛形,你以為的困難或許是南墻
3.dp的每個狀態(tài)粗略的看來都是同一模式下求解,不要天馬行空式地跳出來啊,記住記住,一定要注意狀態(tài)間算法相同,明確定義,補藥雜糅?。。?!2,3寫不下去都是這個原因
4.寫之前把流程稍微寫一下,分析可能性的時候要條理清晰,冷靜一點
5.不要看到求最小值就直接整個數(shù)組賦無窮大,要分析遞推方程的邊界和無窮大是否相加,最好整理到草稿紙上不要上來就寫即使遇到過相同的題目或題目簡單
6.仔細看題
7.不要病急亂投醫(yī)式或非常興奮地一頭扎近可能性,要跳出來顧全大局式分析可能性
咳咳,要不要仔細校準一下,容易眼花QAQ,作者:江海一歸客,原文鏈接:http://www.rzrgm.cn/jhygk/p/19130853

浙公網(wǎng)安備 33010602011771號