Hdu-6212 Zuma(区间DP)

来源:互联网 发布:mac直播音效软件下载 编辑:程序博客网 时间:2024/06/08 19:24
Think about the Zuma Game. You have a row of at most 200
black(0) or white(1) balls on the table at the start. Each three consecutive balls never share the same colour. You also have infinite amount of black and white balls in your hand. On each turn, you can choose a ball in your hand and insert it into the row, including the leftmost place and the rightmost place. Then, if there is a group of three of more balls in the same colour touching, remove these balls. Keep doing this until no more balls can be removed.
Find the minimal balls you have to insert to remove all the balls on the table.
Input
The first line of input contains an integer T (1T100) which is the total number of test cases.
Each test case contains a line with a non-empty string of 0 and 1
describing the row of balls at the start.
Output
For each test case, output the case number and the minimal balls required to insert in a line.
Sample Input
410101101001001100100100101001101011001100
Sample Output
Case #1: 4Case #2: 3Case #3: 3Case #4: 2

分析:我们把连续的小段用二元组表示后(001001 就可以表示成2121),设f[i][j]表示把i到j这段区间全部消除的最小代价,那么我们枚举最后一块j和谁一起消除来进行转移,这样就是

f[i][j] = min(f[i][k-1]+f[k][j]),边界情况是i和j一起消除,这时i和j中间还可以最多夹杂两块1一起消除,但是我的程序只写了中间夹着一个1的情况也ac了,可能是数据弱或者夹着两个1的情况都可以用夹着一个1的情况代替?

#include <bits/stdc++.h>using namespace std;const int INF = 1e9 + 9;int T,n,d[205],f[205][205],g[205][205][2];char str[205];int main(){scanf("%d",&T);for(int t = 1;t <= T;t++){n = 0;scanf("%s",str);int len = strlen(str);int i = 0;while(i < len){if(i == len-1 || str[i+1] != str[i]){d[++n] = 1;i++;}else {d[++n] = 2;i+=2;}} for(int i = 1;i <= n;i++) f[i][i] = d[i] == 1 ? 2 : 1;for(int l = 2;l <= n;l++) for(int i = 1;i+l-1 <= n;i++) { int j = i + l - 1; f[i][j] = INF; for(int k = i+1;k <= j;k++) f[i][j] = min(f[i][j],f[i][k-1] + f[k][j]); if((l-1) & 1) continue; if(d[i] + d[j] >= 3) f[i][j] = min(f[i][j],f[i+1][j-1]); else f[i][j] = min(f[i][j],f[i+1][j-1] + 1); if(d[i] + d[j] == 4) continue; for(int k = i+1;k < j;k++)  if(!((j-k) & 1) && d[k] == 1) f[i][j] = min(f[i][j],f[i+1][k-1] + f[k+1][j-1]); }cout<<"Case #"<<t<<": "<<f[1][n]<<endl;}}



原创粉丝点击