「CQOI2007」「BZOJ1260」塗色paint (區間dp
阿新 • • 發佈:2018-09-21
clas 都是 單位 har rip include cin 給定 amp
Submit: 2057 Solved: 1267
[Submit][Status][Discuss]
輸入僅一行,包含一個長度為n的字符串,即塗色目標。字符串中的每個字符都是一個大寫字母,不同的字母代表不同顏色,相同的字母代表相同顏色。
AAAAA
【樣例輸入1】
RGBGR
【樣例輸出1】
1
【樣例輸出1】
3
1260: [CQOI2007]塗色paint
Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 2057 Solved: 1267
[Submit][Status][Discuss]
Description
假設你有一條長度為5的木版,初始時沒有塗過任何顏色。你希望把它的5個單位長度分別塗上紅、綠、藍、綠、紅色,用一個長度為5的字符串表示這個目標:RGBGR。 每次你可以把一段連續的木版塗成一個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成RRRRR,第二次塗成RGGGR,第三次塗成RGBGR,達到目標。 用盡量少的塗色次數達到目標。Input
Output
僅一行,包含一個數,即最少的塗色次數。Sample Input
Sample Output
【樣例輸入1】AAAAA
【樣例輸入1】
RGBGR
【樣例輸出1】
1
【樣例輸出1】
3
HINT
40%的數據滿足:1<=n<=10
100%的數據滿足:1<=n<=50
題解
一道區間dp。
設F[L][R]為把[L,R]畫完所需的最少次數。初始化F[i][j]=(j-i+1),表示暴力的一格格塗。
轉移時,在[L,R]上枚舉兩個斷點(L‘,R‘),表示在[L,R]上直接覆蓋一個區間[L‘,R‘]。
一開始讓F[L][R]=F[L][L‘-1]+F[L‘][R‘]+F[R‘+1][R],表示把大區間視為三個小區間,不在乎他們邊界可能有緣。
- 如果L‘上的顏色和L‘-1相同,那麽可以少畫一次;
- 如果R‘上的顏色和R‘+1相同,那麽可以少畫一次;
- 如果L‘-1上的顏色和R‘+1上相同,那麽又可以少畫一次。
最後註意一下,因為假設在[L,R]上塗一層時,就算證明了這一層完全融入背景色,也不可能給原區間一個-1的buff,所以最多只能少畫兩次。
答案在F[1][n]。
我現在在懷疑是不是只用一個斷點就可以解決問題
/************************************************************** Problem: 1260 User: qwerta Language: C++ Result: Accepted Time:76 ms Memory:1300 kb ****************************************************************/ #include<iostream> #include<cstring> #include<cstdio> using namespace std; char s[53]; int f[53][53]; int chek(int i,int j) { if(s[i]==s[j])return 1;//相同就可以少畫一筆 else return 0; } int main() { //freopen("a.in","r",stdin); cin>>s; int n=strlen(s); for(int i=n;i;--i) s[i]=s[i-1]; for(int i=1;i<=n;++i) for(int j=i;j<=n;++j) f[i][j]=(j-i+1);//預處理 for(int len=2;len<=n;++len) for(int l=1,r=len;r<=n;++l,++r) { for(int ll=l;ll<=r;++ll) for(int rr=ll;rr<=r;++rr) { int k=f[l][ll-1]+f[rr+1][r]+f[ll][rr],g=0; if(ll-1>=l)g+=chek(ll-1,ll);//左邊界融入背景(///v///) if(rr+1<=r)g+=chek(rr,rr+1);//右邊界融入背景(///v///) if(ll-1>=l&&rr+1<=r)g+=chek(ll-1,rr+1);//左右邊界是一樣噠!(>w<) k-=min(g,2);//最多只能少畫兩筆QAQ f[l][r]=min(f[l][r],k); } } cout<<f[1][n]; return 0; }
「CQOI2007」「BZOJ1260」塗色paint (區間dp