问题描述 POJ1390 方盒游戏
#include<cstring>
#include<iostream>
using namespace std;
struct box_segment {
int color;
int len;
};
struct box_segment segment[200];
int score[200][200][200];//score[i][j][k] 是在i-- j中所有的大块,k是最右边和 J 相同的大块
int click_box(int start, int end, int extra_len) {
int i, result, temp;
if ( score[start][end][extra_len]>0 ) //已经被更新过
return score[start][end][extra_len];
result = segment[end].len + extra_len;
result = result*result;//end和额外的一部分合并
if (start==end) {//如果只有 j 和额外的部分 那么返回(边界条件)
score[start][end][extra_len]= result;
return score[start][end][extra_len];
}
result += click_box(start, end-1, 0);// end和额外的一部分合并 的思路进行下去
i = end - 1;//进行第二种思路,也就是除了直接加消end外 每一种结果的枚举
for ( i = end - 1; i >= start; i-- ) {
if (segment[i].color!=segment[end].color)
continue;
temp = click_box(start, i, segment[end].len + extra_len) + click_box(i+1, end-1, 0);
if ( temp<=result )
continue;
result = temp;
break;
}
score[start][end][extra_len] = result;
return score[start][end][extra_len];
}
int main(int argc, char *argv[]){
int t, n, i, j, end, color;
cin >> t;
for (i=0;i<t;i++) {
cin >> n;
end = 0;
cin >> segment[end].color; //开始进行输入处理
segment[end].len = 1;
for (j=1;j<n;j++) {
cin >> color;
if ( color==segment[end].color )
segment[end].len++;
else {
end++;
segment[end].color = color;
segment[end].len = 1;
}
}//把输入形成大块
memset(score,0,sizeof(score));//dp数组清0
cout << "Case " << i+1 << ": " << click_box(0, end, 0) << endl;//输出DP结果
}
return 0;
}