poj 1390 消除方塊 blocks

2022-06-02 20:27:08 字數 3192 閱讀 7509

今天中午從黑書上看到了的一道例題,動態規劃——>線性模型的例1題。

看書都看不懂!

後面還是看了網上的題解,才漸漸明白......

估計我也說不清楚,所以盡力好了。

樣例:1 2 2 2 2 3 3 3 1

我們建立兩個陣列 :color, num.

其中,color儲存的是顏色值,num是相同顏色的個數。

例如,對上面的樣例來說,我們就有:color[1..4]:=(1,2,3,1). num[1..4]:=(1,4,3,1).

我是看結題報告才懂的。所以覺得如果我沒看題解,我實在是想不出這種狀態來。

f[i,j,k]表示合併第i到第j組色塊所得到的最大分,至於這個k,他其實是第j組之後的某乙個和j組的color值相等的組的長度,現在可能說不清,慢慢講清吧。

該狀態有兩種決策方式:

1.直接合併第j組,再合併i到j-1組。   此時f[i,j,k]:=f[i,j-1,0]+(num[j]+k)^2.(這個又出現了,為什麼會有這個k,他是在上一層遞迴中加入進來的,繼續看下面可能就明白了)。

2.不直接合併而是在i 和j-1 中找到某一組,並且該組的顏色與第j組顏色相同,設為p,先將p+1到j-1組合並,然後p和j因為顏色相同,自然就合成為一組了,假設合併的組還是p。

此時p的長度就為(num[p]+num[j])了,k的作用就在於此:

f[i,j,k]:=f[i,p,k+num[j]]+f[p+1,j-1,0].

為什麼k會變成k+num[j]呢? 看下圖:

如: 先合併 7,8,9,再合併 5,6,10,11,我們可以等效為第二張圖,把5,6,10,11看成整體,由於該整體的num值不再為前者的num值,我們需要乙個附加值來表示當前的num,這個附加的num就是k,顯然k為當前附加值再加上等效後所需要的附加值,在這裡k為2.

所以,方程就的出來了!

f[i,j,k]:=max(f[i,j-1,0]+(num[j]+k)^2,f[i,p,k+num[j]]+f[p+1,j-1,0])。(其中i<=panswer:=f[1,n,0].

接下來就很好辦了.

**:

1 program p1390; //uses math;

2 6 var

7 i,j,k,l,m,q,m2,n,n2:longint;

8 color,num,s:array[0..200]of longint;

9 f:array[0..200,0..200,0..200]of longint;

10 function max(a,b:longint):longint;

11 begin

12 if a>b then exit(a)

13 else exit(b);

14 end;

15 function haha(l,r,k:longint):longint;

16 var

17 i,j,m,n,p:longint;

18 begin

19 if f[l,r,k]<>0 then exit(f[l,r,k]);

20 if l=r then exit((num[r]+k)*(num[r]+k));

21 f[l,r,k]:=haha(l,r-1,0)+(num[r]+k)*(num[r]+k);

22 for i:=l to r-1 do

23 begin

24 if color[i]=color[r] then

25 begin

26 f[l,r,k]:=max(f[l,r,k],haha(l,i,num[r]+k)+haha(i+1,r-1,0));

27 end;

28 end;

29 haha:=f[l,r,k];

30 end;

31 begin

32 assign(input,'p1390.in');

33 reset(input);

34 assign(output,'haha.out');

35 rewrite(output);

36 read(n2);

37 for q:=1 to n2 do

38 begin

39 fillchar(s,sizeof(s),0);

40 fillchar(f,sizeof(f),0);

41 fillchar(num,sizeof(num),0);

42 fillchar(color,sizeof(color),0);

43 read(n);

44 j:=0;

45 for i:=1 to n do

46 read(s[i]);

47 i:=1;

48 while i<=n do

49 begin

50 m:=s[i];

51 inc(j);

52 color[j]:=s[i];

53 while color[j]=s[i] do

54 begin

55 inc(i);

56 inc(num[j]);

57 end;

58 end;

59 writeln('case ',q,': ',haha(1,j,0));

60 end;

61 close(input);

62 close(output);

63 end.

64 65

POJ 1390(三維動規)

poj 1390,三維動規題目,按照大塊分類,參考部落格,重點 1.構造遞迴函式 2.通過三維陣列記憶化儲存 include include include using namespace std struct boxbox 205 int t,n,x,y,idx,dp 205 205 205 in...

POJ 1390 Blocks 區間DP 題解

題意 t組資料,每組資料有n個方塊,給出它們的顏色,每次消去的得分為相同顏色塊個數的平方 要求連續 求最大得分。首先看到這題我們發現我們要把大塊盡可能放在一起才會有最大收益,我們要將相同顏色塊合在一起,我們可以分區間進行處理,便可用區間dp解決,我們嘗試合併區間我們定義狀態f i j 表示合併i j...

題解 P2135 方塊消除

題目傳送門 區間dp 一道模擬賽的題目,然後一直在推 fl,rf fl,r 為 l,r l,r l,r 區間的最大貢獻的轉移一直沒搞出來,後來發現由於刪除一塊會使得兩端顏色相同的塊合併就很難轉移,於是我們多記錄一維 fl,r,sf fl,r,s 表示 l,r l,r l,r 區間內以及在 r,n r...