1. 程式人生 > >[JSOI2007]祖碼Zuma

[JSOI2007]祖碼Zuma

() last 介紹 著名 out line 圖1 mem 需要

題目描述

這是一個流行在Jsoi的遊戲,名稱為祖瑪。 精致細膩的背景,外加神秘的印加音樂襯托,仿佛置身在古老的國度裏面,進行一個神秘的遊戲——這就是著名的祖瑪遊戲。祖瑪遊戲的主角是一只石青蛙,石青蛙會吐出各種顏色的珠子,珠子造型美麗,並且有著神秘的色彩,環繞著石青蛙的是載著珠子的軌道,各種顏色的珠子會沿著軌道往前滑動,石青蛙必需遏止珠子們滾進去軌道終點的洞裏頭,如何減少珠子呢?就得要靠石青蛙吐出的珠子與軌道上的珠子相結合,顏色相同者即可以消失得分!直到軌道上的珠子通通都被清幹凈為止。 或許你並不了解祖瑪遊戲。沒關系。這裏我們介紹一個簡單版本的祖瑪遊戲規則。一條通道中有一些玻璃珠,每個珠子有各自的顏色,如圖1所示。玩家可以做的是選擇一種顏色的珠子(註意:顏色可以任選,這與真實遊戲是不同的)射入某個位置。 技術分享
圖1 圖2中玩家選擇一顆藍色珠子,射入圖示的位置,於是得到一個圖3的局面。技術分享 圖2 技術分享 圖3 當玩家射入一顆珠子後,如果射入的珠子與其他珠子組成了三顆以上連續相同顏色的珠子,這些珠子就會消失。例如,將一顆白色珠子射入圖4中的位置,就會產生三顆顏色相同的白色珠子。這三顆珠子就會消失,於是得到圖5的局面。 技術分享 圖4技術分享 圖5 需要註意的一點是,圖4中的三顆連續的黃色珠子不會消失,因為並沒有珠子射入其中。 珠子的消失還會產生連鎖反應。當一串連續相同顏色的珠子消失後,如果消失位置左右的珠子顏色相同,並且長度大於2,則可以繼續消失。例如,圖6中,射入一顆紅色珠子後,產生了三顆連續的紅色珠子。當紅色珠子消失後,它左右都是白色的珠子,並且一共有四顆,於是白色珠子也消失了。之後,消失位置的左右都是藍色珠子,共有三顆,於是藍色珠子也消失。最終得到圖7的狀態。註意,圖7中的三顆黃色珠子不會消失,因為藍色珠子消失的位置一邊是紫色珠子,另一邊是黃色珠子,顏色不同。 技術分享
圖6 技術分享 圖7 除了上述的情況,沒有其他的方法可以消去珠子。 現在,我們有一排珠子,需要你去消除。對於每一輪,你可以自由選擇不同顏色的珠子,射入任意的位置。你的任務是射出最少的珠子,將全部珠子消去。

輸入

第一行一個整數n(n ≤ 500),表示珠子的個數 第二行n個整數(32位整數範圍內),用空格分割,每個整數表示一種顏色的珠子。

輸出

一個整數,表示最少需要射出的珠子個數。

樣例輸入

9 1 1 2 2 3 3 2 1 1

樣例輸出

1 區間dp f[i][j]表示消除i~j的最小解 兩種情況: 1.消除i~k,k+1~j. 2.消除i+1~j-1(i的顏色與j相同) 先縮點,多個所稱一個點。
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 int n,tot,s[1001],color[1001],f[1001][1001];
 7 int main()
 8 {int last,i,j,k,x;
 9 //freopen("file.in","r",stdin);
10     scanf("%d",&n);
11     last=-1;tot=0;
12     for (i=1;i<=n;i++)
13     {
14         scanf("%d",&x);
15         if (x==last)
16         {
17             s[tot]++;
18         }
19         else
20         {
21             tot++;
22             s[tot]=1;
23             color[tot]=x;
24             last=x;
25         }
26     }
27      n=tot;
28      memset(f,127/3,sizeof(f));
29      for (i=1;i<=n;i++)
30      if (s[i]>=2)
31      f[i][i]=1;
32      else f[i][i]=2;
33     for (i=1;i<=n-1;i++)
34     {
35         for (j=1;j<=n-i;j++)
36          {
37             for (k=j;k<=i+j-1;k++)
38             {
39                 f[j][j+i]=min(f[j][j+i],f[j][k]+f[k+1][j+i]);
40             }
41             if (color[j]==color[j+i])
42             {
43               f[j][j+i]=min(f[j][j+i],f[j+1][j+i-1]+(s[j]+s[j+i]>=3?0:1));
44             }
45             
46          }
47     }
48 cout<<f[1][n];
49 }

[JSOI2007]祖碼Zuma