ZOJ 2624 Popo's Lamps(DP 记忆化搜索)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2624
题目大意:popo要将给定数量的灯变成自己想要的颜色,有一种魔法开关,可以将一连串的灯同时变成同一个颜色。给定灯的数量和popo想要实现的状态,求最小步数
Sample Input
5 RGBGR 4 RGRG 7 ABACADA 0
Sample Output
3 3 4
分析:令f[x][y]表示从第 x 个灯到第 y 个灯变成目标状态的最小花费,则初始时为最大值。而f[x][x]=1。
则f[x][y] =min{ f[x][k-1]+f[k][y] | x<k<y}
当第x,y个灯的目标状态是同一颜色时,就可以一次性将2个灯变成想要的状态
代码如下:
1 # include<iostream> 2 # include<cstdio> 3 # include<cstring> 4 #define MAX 0xFFFFFF 5 using namespace std; 6 char str[51]; 7 int f[51][51],n; 8 int dfs(int x,int y) 9 { 10 int i; 11 int min=y-x+1,temp; 12 for(i=x+1; i<=y; i++) 13 { 14 if(f[x][i-1]==MAX) 15 f[x][i-1]=dfs(x,i-1); 16 17 if(f[i][y]==MAX) 18 f[i][y]=dfs(i,y); 19 20 if(min>f[x][i-1]+f[i][y]) 21 min=f[x][i-1]+f[i][y]; 22 } 23 if(str[x]==str[y]) 24 { 25 if(x+1<n) 26 { 27 if(f[x+1][y]==MAX) 28 temp=dfs(x+1,y); 29 else 30 temp=f[x+1][y]; 31 } 32 else 33 temp=1; 34 if(min>temp) 35 min=temp; 36 if(y-1>0) 37 { 38 if(f[x][y-1]==MAX) 39 temp=dfs(x,y-1); 40 else 41 temp=f[x][y-1]; 42 } 43 else 44 temp=1; 45 if(min>temp) 46 min=temp; 47 if(x+1<n && y-1>0) 48 { 49 if(f[x+1][y-1]==MAX) 50 temp=dfs(x+1,y-1)+1; //额外增加一步将x,y2个灯变成目标状态的步骤 51 else 52 temp=f[x+1][y-1]+1; 53 } 54 else 55 temp=1; 56 if(min>temp) 57 min=temp; 58 } 59 f[x][y]=min; 60 return f[x][y]; 61 62 } 63 int main () 64 { 65 int i,j; 66 while(scanf("%d",&n) && n) 67 { 68 scanf("%s",str); 69 for(i=0; i<n; i++) 70 for(j=i+1; j<n; j++) 71 { 72 f[i][j]=MAX; 73 f[j][i]=1; 74 } 75 for(i=0; i<n; i++) 76 f[i][i]=1; 77 78 printf("%d\n",dfs(0,n-1)); 79 } 80 return 0; 81 }
OJ返回”Non-zero Exit Code“这种错误,是因为最后没有写return 0;或者写成了return 1;之类的,只要改成return 0;就可以了
把每一件简单的事情做好,就是不简单;把每一件平凡的事情做好,就是不平凡!相信自己,创造奇迹~~